SpringBoot 自動裝配原理

  • 2022 年 11 月 6 日
  • 筆記

早期的Spring項目需要添加需要配置繁瑣的xml,比如MVC、事務、資料庫連接等繁瑣的配置。Spring Boot的出現就無需這些繁瑣的配置,因為Spring Boot基於約定大於配置的理念,在項目啟動時候,將約定的配置類自動配置到IOC容器里。這些都因為Spring Boot有自動配置的特性。

Sping Boot 如何實現自動配置

Spring Boot都需要創建一個mian啟動類,而啟動類都含有@SpringBootApplication註解,從啟動類,一步步探索源碼。

@SpringBootApplication註解

Spring Boot 啟動類上都有一個 @SpringBootApplication註解:

@EnableAutoConfiguration註解

@SpringBootApplication 裡面有 @EnableAutoConfiguration 的註解:

AutoConfigurationImportSelector類

@EnableAutoConfiguration註解導入AutoConfigurationImportSelector類:

selectImports()方法

AutoConfigurationImportSelector類找到 selectImports 方法,裡面有getAutoConfigurationEntry方法:

SpringFactoriesLoader.loadFactoryNames() 方法

getAutoConfigurationEntry方法通過SpringFactoriesLoader.loadFactoryNames() 掃描所有含有META-INF/spring.factoriesjar包:

spring-boot-autoconfigure-xxx.jar項目包含META-INF/spring.factories文件,spring.factories是一個鍵值對的形式,掃描該文件下@EnableAutoConfiguration對應類:

自動配置主要由@EnableAutoConfiguration實現,添加了@EnableAutoConfiguration註解,會導入AutoConfigurationImportSelector類,裡面的selectImports方法通過SpringFactoriesLoader.loadFactoryNames()掃描所有含有META-INF/spring.factoriesjar包,將對應key@EnableAutoConfiguration註解全名對應的value類全部裝配到IOC容器中。

Debug 驗證

打開Debug調式模式,在getCandidateConfigurations方法裡面的SpringFactoriesLoader.loadFactoryNames()處設置斷點,查看返回的configurations集合:

第一個元素是tk.mybatis.mapper.autoconfigure.MapperAutoConfiguration是因為引入了通用mapper的依賴:

自動配置原理

原理流程匯總

從上面查看的源碼,可以知道Spring Boot自動配置主要是@EnableAutoConfiguration實現的,@EnableAutoConfiguration註解導入AutoConfigurationImportSelector類,通過selectImports方法調用SpringFactoriesLoader.loadFactoryNames()掃描所有含有META-INF/spring.factories文件的jar包,將spring.factories文件中@EnableAutoConfiguration對應的類注入到IOC容器中。

這些屬性自動配置到IOC之後就無需自己手動配置bean了,Spring Boot中的約定大於配置理念,約定是將需要的配置以約定的方式添加到IOC容器中。

自動配置生效條件

那是不是spring.factories文件對應的配置都會載入到IOC容器中?比如下面的Kafka自動配置類:

@Configuration
@ConditionalOnClass(KafkaTemplate.class)
@EnableConfigurationProperties(KafkaProperties.class)
@Import({ KafkaAnnotationDrivenConfiguration.class, KafkaStreamsAnnotationDrivenConfiguration.class })
public class KafkaAutoConfiguration {

	private final KafkaProperties properties;

	private final RecordMessageConverter messageConverter;

	public KafkaAutoConfiguration(KafkaProperties properties, ObjectProvider<RecordMessageConverter> messageConverter) {
		this.properties = properties;
		this.messageConverter = messageConverter.getIfUnique();
	}

	@Bean
	@ConditionalOnMissingBean(KafkaTemplate.class)
  public KafkaTemplate<?, ?> kafkaTemplate(ProducerFactory<Object, Object> kafkaProducerFactory,
			ProducerListener<Object, Object> kafkaProducerListener) {
      ....
      }

其中有幾個註解:

@ConditionalOnClass
@ConditionalOnMissingBean
  • @ConditionalOnClass表示在類路徑中存在類才會配置該配置類。只有引入相關依賴才會自動配置該配置類。
  • @ConditionalOnMissingBean表示只有不存在對應的類的bean才會自動配置該類。

所以spring.factories裡面並不是所有的bean都會裝配到IOC容器中,只會按需配置對應的bean

總結

  • Spring Boot自動配置原理
    • 1、@EnableAutoConfiguration註解導入AutoConfigurationImportSelector類。
    • 2、執行selectImports方法調用SpringFactoriesLoader.loadFactoryNames()掃描所有jar下面的對應的META-INF/spring.factories文件.
    • 3、限定為@EnableAutoConfiguration對應的value,將這些裝配條件的裝配到IOC容器中。
  • 自動裝配簡單來說就是自動將第三方的組件的bean裝載到IOC容器內,不需要再去寫bean相關的配置,符合約定大於配置理念。
  • Spring Boot基於約定大於配置的理念,配置如果沒有額外的配置的話,就給按照默認的配置使用約定的默認值,按照約定配置到IOC容器中,無需開發人員手動添加配置,加快開發效率。

覺得文章不錯的話,點個贊吧!

Exit mobile version