SpringBoot排除不需要的自動(dòng)配置類DataSourceAutoConfiguration問題
一、排除自動(dòng)配置類的三種方式
以下三種方式可以用來排除任意的自動(dòng)配置類
1.1使用@SpringBootApplication注解排除
使用exclude屬性(value是Class對(duì)象數(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.在項(xiàng)目中創(chuàng)建一個(gè)配置類對(duì)象MyConfig.class,在配置類上使用@EnableAutoConfiguration注解。
使用exclude屬性(value是Class對(duì)象數(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:為什么不能直接在啟動(dòng)類上使用@EnableAutoConfiguration注解,而要重新創(chuàng)建一個(gè)配置類?
因?yàn)锧SpringBootApplication已經(jīng)繼承了@EnableAutoConfiguration,并且@EnableAutoConfiguration注解,是不可在類上重復(fù)使用的注解(換句話說就是使用@SpringBootApplication注解,就相當(dāng)于使用了@EnableAutoConfiguration注解)
所以 我們會(huì)發(fā)現(xiàn)方法一與方法二本質(zhì)上是一樣的只是形式上的差別,底層都是依賴于@EnableAutoConfiguration注解實(shí)現(xiàn)的排除功能。
思考2:@SpringBootApplication注解與@EnableAutoConfiguration的關(guān)系?為什么在@SpringBootApplication注解中配置屬性底層還是使用@EnableAutoConfiguration實(shí)現(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的屬性做了一個(gè)橋接的作用。
1.3.在yml配置文件中添加排除配置
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration注:如果要排除多個(gè)類,使用逗號(hào)隔開
二、為什么可以這樣排除,內(nèi)在邏輯原理研究
springBoot將自動(dòng)配置類添入到spring容器中的部分源碼:
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//獲取注解中配置的需要排除的自動(dòng)配置類信息
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//獲取項(xiàng)目中所有的自動(dòng)配置類
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);
//返回最終需要的自動(dòng)配置類
return new AutoConfigurationEntry(configurations, exclusions);
}- 1.這段代碼中的主要邏輯就是,將項(xiàng)目中所有需要的自動(dòng)配置類的全限定名以字符串?dāng)?shù)組返回出去,后續(xù)spring容器會(huì)將所有的配置類創(chuàng)建成Bean
- 2.所以我們?nèi)N配置排除自動(dòng)配置類的行為,最終都會(huì)在這段代碼邏輯中體現(xiàn)出來,在spring容器初始化他們之前,我們就已經(jīng)提前把他們從初始化的名單中排除了
- 3.我們配置的時(shí)候?yàn)槭裁炊际鞘褂玫念惖娜薅谶@里也得到了解釋,因?yàn)橹挥惺褂萌薅鹲pring容器才能將其創(chuàng)建成對(duì)象。
- 4.還可以得出結(jié)論就是幾種方式可以同時(shí)使用,最終排除的是他們的并集
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中使用異步線程導(dǎo)致Request請(qǐng)求頭丟失問題的解決方法
異步線程請(qǐng)求頭丟失的問題通常發(fā)生在多線程環(huán)境中,特別是在使用 CompletableFuture 或其他異步編程模型時(shí),本文給大家詳細(xì)介紹了SpringBoot中使用異步線程導(dǎo)致Request請(qǐng)求頭丟失問題的原因和解決方法,需要的朋友可以參考下2025-07-07
ConcurrentHashMap線程安全及實(shí)現(xiàn)原理實(shí)例解析
這篇文章主要介紹了ConcurrentHashMap線程安全及實(shí)現(xiàn)原理實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
JAVA中使用FileWriter寫數(shù)據(jù)到文本文件步驟詳解
這篇文章主要介紹了JAVA中使用FileWriter寫數(shù)據(jù)到文本文件步驟詳解,FileWriter類提供了多種寫入字符的方法,包括寫入單個(gè)字符、寫入字符數(shù)組和寫入字符串等,它還提供了一些其他的方法,如刷新緩沖區(qū)、關(guān)閉文件等,需要的朋友可以參考下2023-10-10
Springboot項(xiàng)目中kaptcha驗(yàn)證碼的使用方式
這篇文章主要介紹了Springboot項(xiàng)目中kaptcha驗(yàn)證碼的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Springboot的ThreadPoolTaskScheduler線程池輕松搞定15分鐘不操作自動(dòng)取消訂單
這篇文章主要介紹了Springboot的ThreadPoolTaskScheduler線程池輕松搞定15分鐘不操作自動(dòng)取消訂單,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01

