SpringBoot透過@EnableAutoConfiguration註解開啟自動配置,對jar包下的spring.factories文件進行掃描,這個文件中包含了可以進行自動配置的類,當滿足@Condition註解指定的條件時,便在依賴的支援下進行實例化,註冊到Spring容器中。
通俗的來講,我們之前在寫ssm專案時候,配置了大量座標和配置內容,搭環境的過程在專案開發中佔據了大量時間,SpringBoot的最大的特點就是簡化了各種xml配置內容,所以springboot的自動配置就是用註解來對一些常規的配置做預設配置,簡化xml配置內容,讓你的專案能夠快速運作。
springboot核心設定原理:
自動設定類別都存放在spring-boot-autoconfigure-版本號碼.jar下的org.springframework.boot.autoconfigure中
當我們在application.properties中設定debug=true後啟動容器。可以看到服務器初始化的初始化配置
DispatcherServletAutoConfigratio註冊前端控制器
EmbeddedServletContainerAutoConfiguration註冊容器類型
HttpMessageConvertersAutoConfiguration註冊json或xml處理器
JacksonAutoConfiguration註冊json物件解析器
#如果加入其他功能的依賴,springBoot也會實作這些功能的自動設定
Starter元件是可載入在應用程式中的Maven依賴項項。只有在Maven配置中加入對應的依賴配置,即可使用對應的Starter元件。例如,加入spring-boot-starter-web依賴,就可以用來建構RESTAPI服務,其包含了SpringMVC和Tomcat內嵌容器。
一個完整的Starter元件包含以下兩點:
提供自動設定功能的自動設定模組
提供依賴關係管理崗功能的元件模組,即封裝了元件所有功能,開箱即用。
spring-boot-starter-web依賴原始碼
package org.springframework.boot.autoconfigure.web.servlet; @Configuration @ConditionalOnClass({ServletRequest.class}) @ConditionalOnWebApplication( type = Type.SERVLET ) @EnableConfigurationProperties({ServerProperties.class}) @Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class}) public class ServletWebServerFactoryAutoConfiguration { ...... } @
@SpringBootConfiguration:繼承自Configuration,支援JavaConfig的方式進行配置。
@EnableAutoConfiguration:本文重點講解,主要用於開啟自動設定。
@ComponentScan:自動掃描組件,預設掃描該類所在包及其子包下所有帶有指定註解的類,將它們自動裝配到bean容器中,會被自動裝配的註解包括@Controller 、@Service、@Component、@Repository等。也可以指定掃描路徑。
這個註解是幫助我們自動載入預設配置的,它裡面有兩個關鍵註解@AutoConfigurationPackage和@Import,我們來詳細了解@Import註解。
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //检查自动配置功能是否开启,默认开启 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //加载自动配置的元信息 AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); //获取候选配置类 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //去掉重复的配置类 configurations = removeDuplicates(configurations); //获得注解中被exclude和excludeName排除的类的集合 Set<String> exclusions = getExclusions(annotationMetadata, attributes); //检查被排除类是否可实例化、是否被自动注册配置所使用,不符合条件则抛出异常 checkExcludedClasses(configurations, exclusions); //从候选配置类中去除掉被排除的类 configurations.removeAll(exclusions); //过滤 configurations = filter(configurations, autoConfigurationMetadata); //将配置类和排除类通过事件传入到监听器中 fireAutoConfigurationImportEvents(configurations, exclusions); //最终返回符合条件的自动配置类的全限定名数组 return StringUtils.toStringArray(configurations);
@Import(AutoConfigurationImportSelector.class)註解,這裡導入AutoConfigurationImportSelector類別。這個類別中有一個非常重要的方法——selectImports(),它幾乎涵蓋了元件自動組裝的所有處理邏輯,包括獲得候選配置類別、配置類別去重、排除不需要的配置類別、過濾等,最終傳回符合條件的自動配置類別的全限定名數組。
spring-core套件裡定義了SpringFactoriesLoader類,這個類別實作了檢索META-INF/spring.factories文件,並取得指定介面的配置的功能。在這個類別中定義了兩個對外的方法:
loadFactories根據介面類別取得其實作類別的實例,這個方法傳回的是物件列表。
loadFactoryNames根據介面取得其介面類別的名稱,這個方法傳回的是類別名稱的清單。
上面的兩個方法的關鍵都是從指定的ClassLoader中取得spring.factories文件,並解析得到類別名稱列表,具體程式碼如下:
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)); List<String> result = new ArrayList<String>(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String factoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException ex) { throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex); } }
由程式碼可知,在這個方法中會遍歷整個ClassLoader中所有jar包下的spring.factories檔。也就是說我們可以在自己的jar中配置spring.factories文件,不會影響到其它地方的配置,也不會被別人的配置覆蓋。
spring.factories的是透過Properties解析得到的,所以我們在寫檔案中的內容都是安裝下面這種方式配置的:
com.xxx.interface= com.xxx.classname
以上是SpringBoot自動配置的實作原理是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!