2020-07-31
Java培訓
好程序員Java培訓分享SpringBoot -自動配置原理,概要:SpringBoot啟動的時候加載主配置類,開啟了自動配置功能 @EnableAutoConfiguration
利用EnableAutoConfigurationImportSelector給容器中導入一些組件可以查看selectImports()方法的內容
List configurations = getCandidateConfigurations(annotationMetadata, attributes);獲取候選的配置
SpringFactoriesLoader.loadFactoryNames()掃描所有jar包類路徑下META‐INF/spring.factories
把掃描到的這些文件的內容包裝成properties對象,從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,然后把他們添加在容器中
@EnableAutoConfiguration
作用
@EnableAutoConfiguration這個類很重要,主要的作用是自動載入應用程序所需要的所有默認配置,達到智能的自動配置作用
主要是通過他來實現約定大于配置
源碼
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 自動配置包
@AutoConfigurationPackage
// 給IOC容器導入組件
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class[] exclude() default {};
String[] excludeName() default {};
}
說明
@Import(AutoConfigurationImportSelector.class) 這個注解里的AutoConfigurationImportSelector最為重要
利用AutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都加載到當前SpringBoot創建并使用的IoC容器。
AutoConfigurationImportSelector
selectImports()方法
首先執行selectImports()方法 中調用 getAutoConfigurationEntry()
public String[] selectImports(AnnotationMetadata annotationMetadata) {
...
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
getAutoConfigurationEntry
該方法主要作用獲取EnableAutoConfiguration中的屬性,調用getCandidateConfigurations()方法
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
...
Listconfigurations = getCandidateConfigurations(annotationMetadata, attributes);
..
}
getCandidateConfigurations
獲取候選的配置信息,在候選信息的中使用SpringFactoriesLoader.loadFactoryNames()
protected ListgetCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//加載所有的配置類信息
Listconfigurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
SpringFactoriesLoader
這個類中有一個比較重要的工具類SpringFactoriesLoader主要功能就是從指定的配置文件META-INF/spring-factories加載配置,spring-factories是一個典型的java properties文件,只不過Key和Value都是Java類型的完整類名,
主要的作用:
掃描所有jar包類路徑下 META-INF/spring.factories
把掃描到的這些文件的內容包裝成properties對象 從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,
然后把他們添加在容器中 將類路徑下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中
/**
* 使用內部工具 SpringFactoriesLoader,查找classpath上所有jar包中的META-INF\spring.factories
* 找出其中key為org.springframework.boot.autoconfigure.AutoConfigurationImportFilter的屬性定義的過濾器類并實例化。
* AutoConfigurationImportFilter過濾器可以被注冊到 spring.factories用于對自動配置類做一些限制,在這些自動配置類的字節碼被讀取之前做快速排除處理。
* spring boot autoconfigure 缺省注冊了一個 AutoConfigurationImportFilter :
**/
public static ListloadFactoryNames(Class factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
# 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,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
以MultipartAutoConfiguration(文件上傳)為例
// 表示這是一個配置類
@Configuration
// 判斷當前項目有沒有這些類 有這些類則配置生效
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
// 判斷配置文件中是否存在某個配置spring.servlet.multipart.enabled;
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
// 判斷當前應用是否是web應用,如果是,當前配置類生效
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {
// 配置文件中對應的JavaBean
private final MultipartProperties multipartProperties;
public MultipartAutoConfiguration(MultipartProperties multipartProperties) {
this.multipartProperties = multipartProperties;
}
}
根據當前不同的條件判斷,決定這個配置類是否生效?一但這個配置類生效;這個配置類就會給容器中添加各種組件;這些組件的屬性是從對應的properties類中獲取的,這些類中每一個屬性又是和配置文件綁定;
MultipartProperties
所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝者‘;配置文件能配置什么就可以參照某個功能對應的這個屬性類
@ConfigurationProperties(prefix = "spring.servlet.multipart", ignoreUnknownFields = false)
public class MultipartProperties {
//是否開啟文件上傳功能 默認開啟
private boolean enabled = true;
// 上傳的路徑
private String location;
public void setMaxFileSize(DataSize maxFileSize) {
this.maxFileSize = maxFileSize;
}
public void setMaxRequestSize(DataSize maxRequestSize) {
this.maxRequestSize = maxRequestSize;
}
public void setResolveLazily(boolean resolveLazily) {
this.resolveLazily = resolveLazily;
}
public void setFileSizeThreshold(DataSize fileSizeThreshold) {
this.fileSizeThreshold = fileSizeThreshold;
}
}
spring:
servlet:
multipart:
enabled: true
location: /upload/files
# 支持文件寫入磁盤
file-size-threshold: 0
# 上傳文件總的最大值
max-request-size: 50MB
# 單個文件上傳的大小
max-file-size: 5MB
# 上傳時是否支持懶加載
resolve-lazily: false
小結
SpringBoot啟動會加載大量的自動配置類
自動配置類添加組件的時候,會從properties類中獲取某些屬性。我們可以在配置文件中指定這些屬性的值
xxxxAutoConfigurartion:自動配置類給容器中添加組件
xxxxProperties:對應配置文件中相關屬性,在配置對象可以是setter方法 也有可以是屬性
根據當前不同的條件判斷,決定這個配置類是否生效。
一但這個配置類生效,這個配置類就會給容器中添加各種組件,這些組件的屬性是從對應的properties類中獲取的,這些類里面的每一個屬性又是和配置文件綁定的。
5.所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝者,配置文件能配置什么就可以參照某個功能對應的這個屬性類
@ConfigurationProperties(prefix = "spring.http.encoding") //從配置文件中獲取指定的值和bean的屬性進行綁定
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
精髓:
1)、SpringBoot啟動會加載大量的自動配置類
2)、先看我們需要的功能有沒有SpringBoot默認寫好的自動配置類
3)、再來看這個自動配置類中到底配置了哪些組件(只要我們要用的組件有,我們就不需要再來配置了)
4)、給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性。我們就可以在配置文件中指定這些屬性的值
xxxxAutoConfigurartion:自動配置類;給容器中添加組件;
xxxxProperties:封裝配置文件中相關屬性;
開班時間:2021-04-12(深圳)
開班盛況開班時間:2021-05-17(北京)
開班盛況開班時間:2021-03-22(杭州)
開班盛況開班時間:2021-04-26(北京)
開班盛況開班時間:2021-05-10(北京)
開班盛況開班時間:2021-02-22(北京)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2020-09-21(上海)
開班盛況開班時間:2021-07-12(北京)
預約報名開班時間:2019-07-22(北京)
開班盛況Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號