說明:
本系列基於SpringBoot 2.2.9.RELEASE 版本,對SpringBoot的原理進行分析,一共分爲四節:
SpringBoot原理髮現(一):創建Hello World,對pom依賴以及@SpringBootApplication註解進行分析
SpringBoot原理髮現(二):分析SpringBoot自動配置原理
SpringBoot原理髮現(三):通過主配置類main方法分析SpringBoot啓動配置原理
SpringBoot原理髮現(四):瞭解SpringBoot啓動中的幾個重要回調機制
自動配置原理
1. 自動配置源頭
@EnableAutoConfiguration
@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 {
通過 SpringBoot原理髮現(一)可以得出:
1)SpringBoot啓動的時候加載主配置類,通過@EnableAutoConfiguration開啓了自動配置功能。
2)@EnableAutoConfiguration的作用:
A. @AutoConfigurationPackage:自動配置包,掃描主配置類所在包路徑下面的所有組件並初始化進容器
B. @Import(AutoConfigurationImportSelector.class) :通過源碼,可以看出它是去掃描所有jar包類路徑下面的 META-INF/Spring.factories,並返回EnableAutoConfiguration.class指定的值列表,並添加至容器中,如下圖:
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ ......
上面的每一個XXXAutoConfiguration就是一個組件,它們的作用就是進行自動配置功能。
2. 配置文件配置屬性
打開spring-boot-autoconfigure-2.2.9.RELEASE.jar/META-INF/spring.factories文件,找到其中的EnableAutoConfiguration類指定的值,以HttpEncodingAutoConfiguration爲例
@Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(HttpProperties.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(CharacterEncodingFilter.class) @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration {
其他註解略過..
2.1 @EnableConfigurationProperties(HttpProperties.class)
開啓HttpProperties.class)的配置屬性功能,進入HttpProperties,可以看到如下代碼:
@ConfigurationProperties(prefix = "spring.http") public class HttpProperties {
@ConfigurationProperties(prefix = "spring.http"):該註解是從配置文件中獲取spring.http的值和Bean的屬性進行綁定。
而有哪些屬性可配置在配置文件中就可以參考當前Bean擁有的屬性。
yml文件:
spring:
http:
encoding:
charset: gbk
通過debug如下代碼:
@SpringBootApplication public class DemoApplication { @Autowired private CharacterEncodingFilter characterEncodingFilter; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }
/** * HttpEncodingAutoConfiguration.class */ @Bean @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; }
yaml文件中設置的GBK,自動和HttpProperties的屬性進行了綁定
所以配置文件中能配置哪些屬性,就可以查看XXXProperties類的屬性進行配置。
觀察其他的XXXAutoConfiguration,如:RedisAutoConfiguration , CacheAutoConfiguration
都能發現 @EnableConfigurationProperties(XXXProperties.class)
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration {
可以發現,SpringBoot有很多這種模式: