91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springBoot自動注入原理的示例分析

發布時間:2022-03-03 14:47:42 來源:億速云 閱讀:182 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關springBoot自動注入原理的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

    @SpringBootApplication注解解讀

    為什么我們的啟動類上標注一個@SpringBootApplication注解,再加一個run()方法就可運行起來,可以看出我們的@SpringBootApplication注解是多么的強大。

    @SpringBootApplication
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }

    @SpringBootApplication其實是由三個字注解來合成的。我們可以完全用這個三個注解來替換掉@SpringBootApplication。

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
            @ComponentScan.Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }

    我們來說下這三個注解的一個作用,分別做了什么事情,為什么區區幾個注解就可以讓我們的程序跑起來。

    1.@SpringBootConfiguration

    其實點擊進去就是一個 @Configuration,沒什么特別的,學習過spring的朋友都知道,這是用于標注一個配置類的。

    2.@EnableAutoConfiguration

    重點就是在于@EnableAutoConfiguration 這個注解,我們先看下他的一個構成。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {

    @Inherited

    @Inherited : 如果標注此注解標識子類也可以進行繼承,這個不太重要

    我們先來看.@EnableAutoConfiguration 注解中的@AutoConfigurationPackage注解里面的內容有什么 ? 可以看到導入了一個AutoConfigurationPackages.Registrar類型的組件

    @AutoConfigurationPackage

    @AutoConfigurationPackage:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {

    我們來看下導入的這個AutoConfigurationPackages.Registrar組件做了什么事情?

    registerBeanDefinitions? registerBeanDefinitions是不是就是往我們的容器中添加組件啊?那我們來看看他具體導入了那些組件。你可以將斷點打在這兩個方法上

    	static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    
    		@Override
    		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
    		}
    
    		@Override
    		public Set<Object> determineImports(AnnotationMetadata metadata) {
    			return Collections.singleton(new PackageImports(metadata));
    		}
    
    	}

    springBoot自動注入原理的示例分析

    只要把BeanDefinition注冊進去,往后我們只要調用getBean()就會得到該對象,當然不一定得我們自己調用,spring在底層最后刷新容器的時候,就會初始化所有的單實例bean,這也就是為什么我們直接使用相關注解就可以獲取到該對象的原有。

    getBean()有兩層意思:

    1.容器中有直接從緩存中獲取

    2.容器中沒有直接創建一個,也就是走bean的生命周期創建

    AutoConfigurationImportSelector.class

    @Import(AutoConfigurationImportSelector.class) 核心組件,我們來看看他做了什么事情。

    AutoConfigurationImportSelector他呢繼承了DeferredImportSelector,DeferredImportSelector他呢有個內部接口Group,而Group中又有個方法process()
    所以我們來到AutoConfigurationImportSelector中的process()方法打上斷點進行觀察

    	@Override
    		public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
    			Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
    					() -> String.format("Only %s implementations are supported, got %s",
    							AutoConfigurationImportSelector.class.getSimpleName(),
    							deferredImportSelector.getClass().getName()));
    			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
    					.getAutoConfigurationEntry(annotationMetadata);
    			this.autoConfigurationEntries.add(autoConfigurationEntry);
    			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
    				this.entries.putIfAbsent(importClassName, annotationMetadata);
    			}
    		}

    這個方法一上來就要獲取一些自動注入的條目autoConfigurationEntry,那我們看下他是怎么獲取的,獲取的究竟是什么東西?
    通過堆棧信息我們可以看到是通過invokeBeanDefinitionRegistryPostProcessors()這個方法調用過來的,說明在工廠初始化完畢,你可以往里面仍一些bean的定義信息了。

    進去就是這個方法

    	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    		if (!isEnabled(annotationMetadata)) {
    			return EMPTY_ENTRY;
    		}
    		AnnotationAttributes attributes = getAttributes(annotationMetadata);
    		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    		configurations = removeDuplicates(configurations);
    		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    		checkExcludedClasses(configurations, exclusions);
    		configurations.removeAll(exclusions);
    		configurations = getConfigurationClassFilter().filter(configurations);
    		fireAutoConfigurationImportEvents(configurations, exclusions);
    		return new AutoConfigurationEntry(configurations, exclusions);
    	}

    我們再進入這個方法

    springBoot自動注入原理的示例分析

    在進入loadFactoryNames()方法中

    springBoot自動注入原理的示例分析

    那我們去看看這個文件里面有什么

    springBoot自動注入原理的示例分析

    結合上面的代碼他是不是要加載org.springframework.boot.autoconfigure.EnableAutoConfiguration里面的內容,這些就是一些配置類的信息

    其實這個文件 spring.factories 里面的每一個類的權限的名稱就是一個配置類,只不過springBoot把這些配置類都寫好了,在我們某些場景需要的時候直接給你注入就行,這就說明了我們不用寫那么多配置文件的原因。

    我隨便點擊一個類進去看看

    springBoot自動注入原理的示例分析

    加載完成后: 怎么多?是不是全部第用得上啊?

    springBoot自動注入原理的示例分析

    你看下面的代碼,是不是要排除,移除掉,過濾掉一些啊,排除就是我們自己在注解中寫的排除屬性進行排除,讓后就是經過一系列的篩選過濾。

    springBoot自動注入原理的示例分析

    最后將這些信息put到entries中

    springBoot自動注入原理的示例分析

    springBoot自動注入原理的示例分析

    3.@ComponentScan

    @ComponentScan這個注解的功能就是掃描當前類上標注此注解所在包路徑的所有類,這也就是為什么我們需要把主啟動類放在最外面的原有,如果你想把配置類放在別的地方,那你就得自己手動指定包掃描路徑.

    感謝各位的閱讀!關于“springBoot自動注入原理的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    阳高县| 平和县| 滕州市| 信丰县| 肥城市| 马鞍山市| 夏河县| 上杭县| 甘南县| 讷河市| 平乡县| 河西区| 三穗县| 桐庐县| 格尔木市| 浪卡子县| 阳朔县| 中超| 綦江县| 财经| 昌图县| 孝感市| 黔东| 天台县| 台州市| 来凤县| 金乡县| 乌鲁木齐市| 大理市| 宁陕县| 新平| 紫阳县| 武穴市| 吉林市| 克东县| 汽车| 湄潭县| 莱西市| 大同县| 米脂县| 济南市|