文章來源地址http://www.zghlxwxcb.cn/news/detail-715312.html
主頁傳送門:?? 傳送
概述
??Spring Boot 是一個(gè)用于創(chuàng)建獨(dú)立的、生產(chǎn)級(jí)別的 Spring 應(yīng)用程序的框架。它極大地簡化了 Spring 應(yīng)用程序的開發(fā)過程,其中一個(gè)關(guān)鍵的功能就是自動(dòng)配置(Auto-Configuration)。
??自動(dòng)配置可以根據(jù)項(xiàng)目需求自動(dòng)配置各種服務(wù)和組件,它可以幫助開發(fā)者在不需要顯式配置的情況下,快速地構(gòu)建一個(gè)運(yùn)行的應(yīng)用程序。
??自動(dòng)配置是 Spring Boot 的一個(gè)核心特性,它通過分析項(xiàng)目的依賴和環(huán)境,自動(dòng)地為應(yīng)用程序配置 Spring 配置文件。這意味著開發(fā)者無需手動(dòng)配置大量的 Spring Bean,Spring Boot 會(huì)根據(jù)環(huán)境和項(xiàng)目的依賴來智能地為應(yīng)用程序創(chuàng)建所需的 Bean。
原理
??Spring Boot的自動(dòng)配置原理基于Java的反射機(jī)制和Spring的IoC容器。它通過讀取項(xiàng)目中的配置文件(如application.properties或application.yml),根據(jù)配置信息自動(dòng)創(chuàng)建和配置各種服務(wù)。
可以概括為以下幾個(gè)步驟:
Spring Boot Starter
??Spring Boot 項(xiàng)目通常依賴于所謂的 “Starters”,這是一組預(yù)定義了常用庫的依賴集合。Starters 包含了應(yīng)用程序所需的所有依賴,比如 Web Starter 會(huì)包含用于構(gòu)建 Web 應(yīng)用程序的所有必要庫。
spring.factories 文件
??在每個(gè) Starter 的 META-INF/spring.factories
文件中,定義了一系列的自動(dòng)配置類。這些自動(dòng)配置類會(huì)在應(yīng)用程序啟動(dòng)時(shí)被 Spring Boot 自動(dòng)掃描和加載。
@ConditionalOnX 注解
??在自動(dòng)配置類中,通常會(huì)使用 @ConditionalOnX
注解來控制該自動(dòng)配置是否生效。這個(gè)注解會(huì)根據(jù)特定的條件(比如類是否在類路徑中、特定的 Bean 是否存在等)來決定是否應(yīng)用這個(gè)配置。
配置 Bean
??自動(dòng)配置類會(huì)定義一些必要的 Bean,并使用 @Configuration
注解將它們標(biāo)記為配置類。這些 Bean 會(huì)在 Spring 上下文中被自動(dòng)注冊(cè)。
配置屬性
??自動(dòng)配置類還可以通過讀取 application.properties
或 application.yml
文件中的屬性來自定義它們的行為。這樣,開發(fā)者可以根據(jù)需要進(jìn)行定制。
源碼剖析
Spring Boot 應(yīng)用的啟動(dòng)類一般均位于src/main/java根路徑下
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
復(fù)合Annotation
??@SpringBootApplication
開啟組件掃描和自動(dòng)配置,而SpringApplication.run
則負(fù)責(zé)啟動(dòng)引導(dǎo)應(yīng)用程序。@SpringBootApplication
是一個(gè)復(fù)合Annotation
,它將三個(gè)有用的注解組合在一起:
@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 {
// ...省略內(nèi)容
}
??@SpringBootConfiguration
就相當(dāng)于@Configuration
,它是 Spring 框架的注解,標(biāo)明該類是一個(gè)JavaConfig
配置類。而@ComponentScan
啟用組件掃描。
@EnableAutoConfiguration
??@EnableAutoConfiguration
注解表示開啟 Spring Boot 自動(dòng)配置功能,Spring Boot 會(huì)根據(jù)應(yīng)用的依賴、自定義的 bean、classpath 下有沒有某個(gè)類 等等因素來猜測(cè)你需要的 bean,然后注冊(cè)到 IOC 容器中。
??@EnableAutoConfiguration
是如何推算出需求的?首先來看下它的定義:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// ...省略內(nèi)容
}
??重點(diǎn)關(guān)注點(diǎn)在@Import({AutoConfigurationImportSelector.class})
@Import
注解用于導(dǎo)入類,并將這個(gè)類作為一個(gè) bean 的定義注冊(cè)到容器中,這里它將把EnableAutoConfigurationImportSelector
作為 bean 注入到容器中,而這個(gè)類會(huì)將所有符合條件的@Configuration
配置都加載到容器中。
??查看EnableAutoConfigurationImportSelector
代碼可以看到:
AutoConfigurationImportSelector
??AutoConfigurationImportSelector
實(shí)現(xiàn)了DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered
這些接口。核心代碼為
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
//...
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
}
再來具體看getAutoConfigurationEntry
方法具體是如何判斷哪些是需要導(dǎo)入的。
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
??annotationMetadata
參數(shù)是一個(gè)元數(shù)據(jù)接口,它提供了對(duì)注解元數(shù)據(jù)的訪問權(quán)限,通常用于在運(yùn)行時(shí)檢查類上的注解。
??getAutoConfigurationEntry(annotationMetadata)
方法會(huì)根據(jù)傳入的 annotationMetadata
返回一個(gè) AutoConfigurationEntry
對(duì)象。
??AutoConfigurationEntry
是一個(gè)內(nèi)部類,用于封裝自動(dòng)配置項(xiàng)的信息,包括該自動(dòng)配置項(xiàng)的類名、條件(Conditions)等信息。
??通過獲取到的 autoConfigurationEntry
對(duì)象,Spring Boot 就能夠知道哪些自動(dòng)配置類需要被導(dǎo)入,從而將它們注冊(cè)到 Spring 上下文中。文章來源:http://www.zghlxwxcb.cn/news/detail-715312.html
如果喜歡的話,歡迎 ??關(guān)注 ??點(diǎn)贊 ??評(píng)論 ??收藏 ??一起討論 你的支持就是我??創(chuàng)作的動(dòng)力! ??????
到了這里,關(guān)于1024程序員節(jié)特輯:【Spring Boot自動(dòng)配置原理揭秘】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!