springboot2.x基礎教程:自動裝配原理與條件註解
阿新 • • 發佈:2020-09-10
> spring Boot採用約定優於配置的方式,大量的減少了配置檔案的使用。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。
> 當springboot啟動的時候,預設在容器中注入許多AutoCongfigution類。在我們加入spring-boot-stareter-xx時,XXXAutoConfiguration類根據對應的條件,自動選擇裝配對應的Bean例項注入IOC容器中。
## 先說結論
1. SpringBoot啟動的時候載入主配置類,開啟了自動配置功能@EnableAutoConfiguration
2. @EnableAutoConfiguration Import的AutoConfigurationImportSelector中程式碼最終呼叫SpringFactoriesLoader.loadSpringFactories掃描了Jar包的META-INF/spring.factories檔案載入了大量的XXAutoConfiguration類
3. AutoConfiguration類配合Conditonal註解與ConfigurationProperties配置類在特定條件下自動裝配我們需要的Bean到IOC容器中。
## 注入AutoConfiguration類核心原始碼分析
SpringBoot的主啟動類上需要加入@SpringBootApplication註解,我們看看該註解的原始碼。
```java
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
//...省略
}
```
實際是@EnableAutoConfigurtaion註解起作用。
```java
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class[] exclude() default {};
String[] excludeName() default {};
}
```
看到@Import註解是不是很熟悉,該註解作用見教程@Enable原理,主要能夠匯入下面3種情況中的Bean。
1. 允許注入使用@Configuration註解的類
2. 允許使用實現ImportSelectorj介面的類,注入selectImports返回的類
3. 允許是實現了ImportBeanDefinitionRegistrar介面的類
AutoConfigurationImportSelector中selectImports原始碼
```java
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
```
其中**AutoConfigurationImportSelector.getAutoConfigurationEntry**呼叫**AutoConfigurationImportSelector.getCandidateConfigurations**呼叫**SpringFactoriesLoader.loadFactoryNames**呼叫**SpringFactoriesLoader.loadSpringFactories**。
其中**SpringFactoriesLoader.loadSpringFactories**從指定的配置檔案META-INF/spring.factories載入配置。
```java
private st