<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
不知道大家第一次搭SpringBoot環境的時候,有沒有覺得非常簡單。無須各種的組態檔,無須各種繁雜的pom座標,一個main方法,就能run起來了。與其他框架整合也賊方便,使用EnableXXXXX註解就可以搞起來了!
所以今天來講講SpringBoot是如何實現自動設定的~
@SpringBootApplication: Spring Boot應用標註在某個類上說明這個類是SpringBoot的主設定類,SpringBoot需要執行這個類的main方法來啟動SpringBoot應用;
先看一下@SpringBootApplication註解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication {
註解說明:
@SpringBootConfiguration:
Spring Boot的設定類;標註在某個類上,表示這是一個Spring Boot的設定類(對@Configuration做了繼承,目的只是標識是springboot的設定類);
@EnableAutoConfiguration:
開啟自動設定功能的關鍵註解,就是通過這個註解把所需的bean自動裝配到spring容器中。
再看一下這個註解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {
其中有一個通過@Import註解匯入了一個重要的物件AutoConfigurationImportSelector,它實現了DeferredImportSelector介面,
關於這個介面的的作用是延遲匯入所有自動裝配的BeanDefinition,把這些BeanDefinition和生成的bean對比其它的bean是放在最後匯入,這樣後面使用springboot封裝的@ConditionalOnBean、@ConditionalOnMissingBean 、@ConditionalOnClass、@ConditionalOnMissingClass、@ConditionalOnProperty判斷這個類需不需要裝配具有前提條件。
例如:如果我們自己在專案中設定類mybatis的SqlSessionFactory物件,則springboot中則不會再進行自動裝配,
自定義
@Bean
Public SqlSessionFactory getSqlSessionFactory (){
…
Return sqlSessionFactory ;
}
再看一下AutoConfigurationImportSelector物件:
其實現了延遲匯入bean的介面DeferredImportSelector
這個可以往spring容器中注入物件。
String[] selectImports(AnnotationMetadata annotationMetadata) 此方法是在public Class<? extends Group> getImportGroup() 方法返回null的情況下,才執行生效的。否則不生效,所以此方法不做特別講解。
主要看實現的方法:
@Override public Class<? extends Group> getImportGroup() { return AutoConfigurationGroup.class; }
在spring中會執行AutoConfigurationGroup類的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())); //在此方法中找到候選自動轉入的bean的class的name。 AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector) .getAutoConfigurationEntry(annotationMetadata); this.autoConfigurationEntries.add(autoConfigurationEntry); for (String importClassName : autoConfigurationEntry.getConfigurations()) { this.entries.putIfAbsent(importClassName, annotationMetadata); } }
此方法的作用是找出所有候選的需要自動裝配bean的class物件名字;都封裝在AutoConfigurationEntry物件中,然後裝入全域性變數中待後面方法的使用。
看一下如何找到候選待裝配的bean,呼叫下面的方法:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } //此方法就是獲取註解中設定的排除裝配的bean AnnotationAttributes attributes = getAttributes(annotationMetadata); //此方法就是獲取所有的候選的bean List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //根據名稱去重 configurations = removeDuplicates(configurations); //獲取排除的Bean Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); //進行排除 configurations.removeAll(exclusions); //這一步也是比較重要的,就是根據那些@Condition註解從候選的class中選擇符合條件的 configurations = getConfigurationClassFilter().filter(configurations); //執行自動匯入的監聽事件AutoConfigurationImportListener fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); }
那如何獲取到合適的class的呢?
1、是獲取專案中(pom.xml匯入jar包)META-INF/spring.factories檔案中設定的的所有key-value
2、所以找到Map<String, List>型別的資料;
3、根據可以org.springframework.boot.autoconfigure.EnableAutoConfiguration作為key找到其中的List資料;
4、這些就是所有候選的class的名字
如下就是候選的class
configurations = getConfigurationClassFilter().filter(configurations);
這一步是根據候選class中的以@Condition開頭註解來過濾合適的自動裝配的bean。
先獲取三個如果所示的過濾器物件;然後傳入所有候選的class名字進行過濾,返回合適的自動裝配的bean,以mybatis為例:
根據這些條件進行過濾是否裝入bean;
最後一List返回所有符合條件的設定類;也會在list組內進行排序:根據@Order、@AutoConfigureAfter、@AutoConfigureBefore註解進行排序
AutoConfigurationGroup#selectImports
我們可以看到過濾完之後,只剩下少量作為的物件作為設定類;
總結:
Spring自動裝配的原理是:
1、通過延遲匯入bean的物件DeferredImportSelector批次的把符合條件的設定類class名稱進行返回;
2、然後根據上步返回的class名稱,也就是元件的設定類全限定名,把元件的設定物件裝配到spring容器中;
3、而springboot篩選合適的元件設定類是通過獲取META-INF/spring.factorys檔案下key為org.springframework.boot.autoconfigure.EnableAutoConfiguration
的calss名稱value只集合,然後根據這些class上面的相關以@ConditionalOn
開通的註解來過濾正在的設定類的class名稱進行返回。
@xxxConditional根據當前不同的條件判斷,決定這個設定類是否生效?
@Conditional派生註解(Spring註解版原生的@Conditional作用)
作用:必須是@Conditional指定的條件成立,才給容器中新增元件,設定配裡面的所有內容才生效;
到此這篇關於Springboot @Configuration與自動設定詳解的文章就介紹到這了,更多相關Springboot @Configuration內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45