摘要:一源碼分析簡(jiǎn)述聲明本人使用的開(kāi)發(fā)工具為了解查看源碼,眼睛掃到,這很關(guān)鍵。注版本是,該類繼承了。這說(shuō)明了依賴于配置文件,文件中鍵為對(duì)應(yīng)的配置項(xiàng)注全類名加載到容器。如果用方法獲得,會(huì)報(bào)錯(cuò),所以呀用的方法。
一、源碼分析簡(jiǎn)述
聲明:本人使用的開(kāi)發(fā)工具為IDEA
1、@EnableAutoConfiguration了解
查看源碼,眼睛掃到@Import(AutoConfigurationImportSelector.class),這很關(guān)鍵。注版本1.5是EnableAutoConfigurationImportSelector,該類繼承了AutoConfigurationImportSelector。
2、再查看源碼AutoConfigurationImportSelector.java,里面用到了方法getCandidateConfigurations()
然后按住Ctrl點(diǎn)進(jìn)去,查看方法getCandidateConfigurations(),了解他會(huì)到classpath下的讀取META-INF/spring.factories文件的配置,并返回一個(gè)字符串?dāng)?shù)組。這說(shuō)明了@EnableAutoConfiguration-- 依賴于META-INF/spring.factories配置文件,spring.factories文件中鍵key為 org.springframework.boot.autoconfigure.EnableAutoConfiguration ,對(duì)應(yīng)的配置項(xiàng)(注:全類名)加載到spring容器。
前提:只有spring.boot.enableautoconfiguration為true(默認(rèn)為true)的時(shí)候,才啟用自動(dòng)配置
該注解@EnableAutoConfiguration還可以進(jìn)行排除,排除方式有2中,一是根據(jù)classes來(lái)排除(exclude),二是根據(jù)class names(excludeName)來(lái)排除
其內(nèi)部實(shí)現(xiàn)的核心關(guān)鍵點(diǎn)有二
1)ImportSelector 該接口的方法的返回值都會(huì)被納入到spring 的容器管理 2)SpringFactoriesLoader 該類可以從classpath中搜索META-INF/spring.factories配置文件,并讀取配置
二、詳細(xì)步驟
1、創(chuàng)建兩個(gè)maven Module ,當(dāng)然你也可以創(chuàng)建一個(gè)pom文件主要代碼如下
1)springboot3的maven module 的POM文件UTF-8 1.8 1.8 4.12 org.springframework.boot spring-boot-dependencies 1.5.10.RELEASE import pom 2)springboot3-core-bean的maven module 的POM文件 org.springframework.boot spring-boot-starter com.fai springboot03-core-bean 1.0-SNAPSHOT junit junit ${junit.version} com.fai springboot03-core-bean 1.0-SNAPSHOT UTF-8 1.8 1.8 4.12 org.springframework spring-context 4.3.12.RELEASE junit junit ${junit.version}
2、創(chuàng)建類
1)Car.java public class Car {} 2)CarConfiguration.java @Configuration public class CarConfiguration { @Bean public Car getCar() { return new Car(); } } 3)Music.java public class Music {} 4)RunnableConfiguration.java /** * Runnable配置類 */ @Configuration public class RunnableConfiguration { @Bean public Runnable getRunnable1() { return () -> {}; } } 5)META-INF/spring.factories #查看@EnableAutoConfiguration 注解源碼,--"spring.boot.enableautoconfiguration"; #默認(rèn)true . 如果改成false,EnableAutoConfiguration注解不起作用 spring.boot.enableautoconfiguration=true 6)測(cè)試 @EnableAutoConfiguration // 根據(jù)應(yīng)用所聲明的依賴來(lái)對(duì)Spring框架進(jìn)行自動(dòng)配置 // 根據(jù)class排除 //@EnableAutoConfiguration(exclude = {CarConfiguration.class,Music.class}) // 根據(jù)class names排除,全類名 //@EnableAutoConfiguration(excludeName = {"com.fai.bean.RunnableConfiguration"}) @ComponentScan public class App { public static void main(String[] args) { SpringApplication app = new SpringApplication(App.class); ConfigurableApplicationContext context = app.run(args); // 獲取Runnable 類對(duì)象的實(shí)例 // System.out.println(context.getBean(Runnable.class)); System.out.println(context.getBeansOfType(Runnable.class)); // 獲取Car 類的Bean System.out.println(context.getBeansOfType(Car.class)); // 獲取Music 類的Bean System.out.println(context.getBeansOfType(Music.class)); context.close(); } } 7)在測(cè)試中,更改配置文件application.properties中的spring.boot.enableautoconfiguration的值為false后,獲取不到Bean #查看@EnableAutoConfiguration 注解源碼,"spring.boot.enableautoconfiguration"; #默認(rèn)true,如果改成false,EnableAutoConfiguration注解不起作用 spring.boot.enableautoconfiguration=false
在第7)的改為false測(cè)試結(jié)果如下圖,是空的。如果用getBean方法獲得Bean,會(huì)報(bào)錯(cuò),所以呀用的getBeansOfType方法。
三、附上關(guān)鍵源碼
1、@EnableAutoConfiguration 注解
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class) // 1.5版本,我用的
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ Class>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ String[] excludeName() default {};
}
2、EnableAutoConfigurationImportSelector 源碼
@Deprecated
public class EnableAutoConfigurationImportSelector
extends AutoConfigurationImportSelector { @Override protected boolean isEnabled(AnnotationMetadata metadata) { if (getClass().equals(EnableAutoConfigurationImportSelector.class)) { return getEnvironment().getProperty( EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true); } return true; }
}
3、EnableAutoConfigurationImportSelector 的父類AutoConfigurationImportSelector 源碼關(guān)鍵方法摘要
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { // 配置文件中的默認(rèn)配置為true,我改過(guò)false的那個(gè) return NO_IMPORTS; } try { AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); Listconfigurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); configurations = sort(configurations, autoConfigurationMetadata); Set exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return configurations.toArray(new String[configurations.size()]); } catch (IOException ex) { throw new IllegalStateException(ex); } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71022.html
摘要:所以,所謂的自動(dòng)裝配,實(shí)際上就是如何自動(dòng)將裝載到容器中來(lái)。實(shí)際上在版本中,模塊驅(qū)動(dòng)注解的出現(xiàn),已經(jīng)有了一定的自動(dòng)裝配的雛形,而真正能夠?qū)崿F(xiàn)這一機(jī)制,還是在版本中,條件注解的出現(xiàn)。,我們來(lái)看一下的自動(dòng)裝配是怎么一回事。在前面的分析中,Spring Framework一直在致力于解決一個(gè)問(wèn)題,就是如何讓bean的管理變得更簡(jiǎn)單,如何讓開(kāi)發(fā)者盡可能的少關(guān)注一些基礎(chǔ)化的bean的配置,從而實(shí)現(xiàn)自動(dòng)裝...
摘要:?jiǎn)?dòng)原理和執(zhí)行原理分析一的啟動(dòng)原理我們打開(kāi),注意看下面兩個(gè)依賴我們第一步是繼承了父項(xiàng)目,然后在添加啟動(dòng)器的依賴,項(xiàng)目就會(huì)自動(dòng)給我們導(dǎo)入關(guān)于項(xiàng)目所需要的配置和。 上一篇我們看到,我們很輕松的完成了項(xiàng)目的構(gòu)建,那么SpringBoot是如何做到的呢,在使用的使用又有哪些通用配置和注意事項(xiàng)呢? 其實(shí)SpringBoot給我們做了大量的自動(dòng)配置功能,我們只需要引入對(duì)應(yīng)的啟動(dòng)器就可以直接使用,作...
摘要:前言用過(guò)的肯定很熟悉,它其中有個(gè)重要的特性,就是自動(dòng)配置平時(shí)習(xí)慣的一些設(shè)置的配置作為默認(rèn)配置。提倡無(wú)配置文件的理念,使用生成的應(yīng)用完全不會(huì)生成任何配置代碼與配置文件。 前言 用過(guò)springboot的肯定很熟悉,它其中有個(gè)重要的特性,就是自動(dòng)配置(平時(shí)習(xí)慣的一些設(shè)置的配置作為默認(rèn)配置)。springboot提倡無(wú)XML配置文件的理念,使用springboot生成的應(yīng)用完全不會(huì)生成任何配...
摘要:常規(guī)的配置讓開(kāi)發(fā)人員將更多的經(jīng)歷耗費(fèi)在了配置文件上。其中有三個(gè)注解,,。以前我們需要配置的東西,幫我們自動(dòng)配置,告訴開(kāi)啟自動(dòng)配置功能,這樣自動(dòng)配置才能生效。 為什么需要自動(dòng)化配置 ??在常規(guī)的spring應(yīng)用程序中,充斥著大量的配置文件,我們需要手動(dòng)去配置這些文件,如配置組件掃描、視圖解析器、http編碼等等。常規(guī)的配置讓開(kāi)發(fā)人員將更多的經(jīng)歷耗費(fèi)在了配置文件上。而這些配置都是一些固定模...
摘要:常規(guī)的配置讓開(kāi)發(fā)人員將更多的經(jīng)歷耗費(fèi)在了配置文件上。其中有三個(gè)注解,,。以前我們需要配置的東西,幫我們自動(dòng)配置,告訴開(kāi)啟自動(dòng)配置功能,這樣自動(dòng)配置才能生效。 為什么需要自動(dòng)化配置 ??在常規(guī)的spring應(yīng)用程序中,充斥著大量的配置文件,我們需要手動(dòng)去配置這些文件,如配置組件掃描、視圖解析器、http編碼等等。常規(guī)的配置讓開(kāi)發(fā)人員將更多的經(jīng)歷耗費(fèi)在了配置文件上。而這些配置都是一些固定模...
閱讀 2419·2021-09-22 15:15
閱讀 656·2021-09-02 15:11
閱讀 1798·2021-08-30 09:48
閱讀 1898·2019-08-30 15:56
閱讀 1508·2019-08-30 15:52
閱讀 2059·2019-08-30 15:44
閱讀 447·2019-08-29 16:29
閱讀 1552·2019-08-29 11:06