好程式設計師Java培訓分享SpringBoot -自動配置原理
好程式設計師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) {
...
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
..
}
getCandidateConfigurations
獲取候選的配置資訊, 在候選資訊的中使用 SpringFactoriesLoader.loadFactoryNames()
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// 載入所有的配置類資訊
List<String> configurations = 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 List<String> loadFactoryNames(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: 封裝配置檔案中相關屬性;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2708270/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師Java培訓分享SpringBoot -啟動流程程式設計師JavaSpring Boot
- 好程式設計師Java培訓分享SpringBoot -YAML程式設計師JavaSpring BootYAML
- 好程式設計師Java培訓分享SpringBoot入門篇程式設計師JavaSpring Boot
- 好程式設計師Java培訓分享Spring Ioc的原理程式設計師JavaSpring
- 好程式設計師Java培訓分享Java程式設計技巧程式設計師Java
- 好程式設計師Java培訓分享Java程式設計師技能提升指南程式設計師Java
- 好程式設計師Java培訓分享Java讀寫Properties配置檔案程式設計師Java
- 好程式設計師Java培訓分享maven-概述程式設計師JavaMaven
- 好程式設計師Java培訓分享BigDecimal的用法程式設計師JavaDecimal
- 好程式設計師Java培訓分享註解與反射原理說明程式設計師Java反射
- 好程式設計師Java培訓分享如何快速入門Java程式設計程式設計師Java
- 好程式設計師Java培訓分享Java程式設計師常用的工具類庫程式設計師Java
- 好程式設計師Java培訓分享20個Java程式設計師基礎題程式設計師Java
- 好程式設計師Java培訓分享Java之反射技術程式設計師Java反射
- 好程式設計師Java培訓分享如何快速入門Java程式設計師Java
- 好程式設計師Java培訓分享Java包是什麼?程式設計師Java
- 好程式設計師Java培訓分享Java多執行緒程式設計師Java執行緒
- 好程式設計師Java培訓分享本地快取如何設計程式設計師Java快取
- 好程式設計師Java培訓分享For迴圈詳解程式設計師Java
- 好程式設計師Java培訓分享Java動態代理機制詳解程式設計師Java
- 好程式設計師Java培訓分享學Java程式設計要注意什麼程式設計師Java
- 好程式設計師Python培訓分享Python配置gRPC環境程式設計師PythonRPC
- 好程式設計師Java培訓分享Java和HTML的區別?程式設計師JavaHTML
- 好程式設計師Java培訓分享Java物件導向概念解析程式設計師Java物件
- 好程式設計師Java培訓分享Java初學者必讀程式設計師Java
- 好程式設計師Python培訓分享API自動化實戰詳解程式設計師PythonAPI
- 好程式設計師Java培訓分享MySQL算術運算子程式設計師JavaMySql
- 好程式設計師Java培訓分享Mybatis面試題集合程式設計師JavaMyBatis面試題
- 好程式設計師Java培訓分享Java EE與Java的區別程式設計師Java
- 好程式設計師Java培訓分享jdk安裝與環境變數配置程式設計師JavaJDK變數
- 好程式設計師Java培訓分享Java面試題集合篇一程式設計師Java面試題
- 好程式設計師Java培訓分享Java面試題集合篇二程式設計師Java面試題
- 好程式設計師Java培訓分享學習Java需要哪些基礎程式設計師Java
- 好程式設計師Java培訓分享面試Java的注意事項程式設計師Java面試
- 好程式設計師Java培訓分享Java中級面試題合集程式設計師Java面試題
- 好程式設計師Java培訓分享Java集合的兩種排序方法程式設計師Java排序
- 好程式設計師Java培訓分享學Java需要什麼基礎?程式設計師Java
- 好程式設計師Java培訓分享Java基礎知識總結程式設計師Java