SpringBoot排除不需要的自動配置類DataSourceAutoConfiguration問題
一、排除自動配置類的三種方式
以下三種方式可以用來排除任意的自動配置類
1.1使用@SpringBootApplication注解排除
使用exclude屬性(value是Class對象數(shù)組)
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
或者excludeName屬性(value是類的全限定名字符串?dāng)?shù)組)
@SpringBootApplication(excludeName = {"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"}) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
1.2使用@EnableAutoConfiguration注解排除
1.在項目中創(chuàng)建一個配置類對象MyConfig.class,在配置類上使用@EnableAutoConfiguration注解。
使用exclude屬性(value是Class對象數(shù)組)
@Configuration @EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class) public class MyConfig { }
或者excludeName屬性(value是類的全限定名字符串?dāng)?shù)組)
@Configuration @EnableAutoConfiguration(excludeName = {"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"}) public class MyConfig { }
思考1:為什么不能直接在啟動類上使用@EnableAutoConfiguration注解,而要重新創(chuàng)建一個配置類?
因為@SpringBootApplication已經(jīng)繼承了@EnableAutoConfiguration,并且@EnableAutoConfiguration注解,是不可在類上重復(fù)使用的注解(換句話說就是使用@SpringBootApplication注解,就相當(dāng)于使用了@EnableAutoConfiguration注解)
所以 我們會發(fā)現(xiàn)方法一與方法二本質(zhì)上是一樣的只是形式上的差別,底層都是依賴于@EnableAutoConfiguration注解實現(xiàn)的排除功能。
思考2:@SpringBootApplication注解與@EnableAutoConfiguration的關(guān)系?為什么在@SpringBootApplication注解中配置屬性底層還是使用@EnableAutoConfiguration實現(xiàn)的呢?
@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 { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class) 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 */ @AliasFor(annotation = EnableAutoConfiguration.class) String[] excludeName() default {};
我們可以看出源碼中使用了注解:
@AliasFor(annotation = EnableAutoConfiguration.class)
將@SpringBootApplication的exclude和excludeName屬性與@EnableAutoConfiguration的屬性做了一個橋接的作用。
1.3.在yml配置文件中添加排除配置
spring: autoconfigure: exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
注:如果要排除多個類,使用逗號隔開
二、為什么可以這樣排除,內(nèi)在邏輯原理研究
springBoot將自動配置類添入到spring容器中的部分源碼:
protected AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } //獲取注解中配置的需要排除的自動配置類信息 AnnotationAttributes attributes = getAttributes(annotationMetadata); //獲取項目中所有的自動配置類 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); //獲取配置文件中配置的需要排除的類信息,并與之前的注解中配置的數(shù)據(jù)整合在一起 Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); //將需要排除的類信息刪除 configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); //返回最終需要的自動配置類 return new AutoConfigurationEntry(configurations, exclusions); }
- 1.這段代碼中的主要邏輯就是,將項目中所有需要的自動配置類的全限定名以字符串?dāng)?shù)組返回出去,后續(xù)spring容器會將所有的配置類創(chuàng)建成Bean
- 2.所以我們?nèi)N配置排除自動配置類的行為,最終都會在這段代碼邏輯中體現(xiàn)出來,在spring容器初始化他們之前,我們就已經(jīng)提前把他們從初始化的名單中排除了
- 3.我們配置的時候為什么都是使用的類的全限定名在這里也得到了解釋,因為只有使用全限定名spring容器才能將其創(chuàng)建成對象。
- 4.還可以得出結(jié)論就是幾種方式可以同時使用,最終排除的是他們的并集
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn)
FreeMarker它允許開發(fā)人員使用模板和數(shù)據(jù)來生成輸出文本,如HTML網(wǎng)頁、電子郵件、配置文件和源代碼等,本文主要介紹了SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn),感興趣的可以了解一下2024-03-03springboot實現(xiàn)jar運行復(fù)制resources文件到指定的目錄(思路詳解)
這篇文章主要介紹了springboot實現(xiàn)jar運行復(fù)制resources文件到指定的目錄,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04并發(fā)編程之Java內(nèi)存模型鎖的內(nèi)存語義
這篇文章主要介紹了并發(fā)編程之Java內(nèi)存模型鎖的內(nèi)存語義,鎖的作用是讓臨界區(qū)互斥執(zhí)行,本文只要圍繞鎖的內(nèi)存語義展開全文內(nèi)容,需要的小伙伴可以參考一下2021-11-11