日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Boot自动配置原理分析

發布時間:2024/9/30 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot自动配置原理分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、寫在前面

隨著時間的遷移Spring Boot 越來越多的出現在Java 后端程序員的視野中,Spring Boot 之所以會那么流行,很大的一個原因是自身集成了很多的Bean,簡化了傳統Sring 項目瑣碎的文件配置。

這些自動配置的Bean 在入口類啟動的時候完成注入,并由Spring 的IoC 容器管理。所以在使用某些Bean的時候,不需要再由我們自動配置。下面我們就通過源碼的方式來看看Spring Boot 是如何實現自動配置的。

二、查看自動配置的Bean

我們可以在Spring Boot 項目的配置文件(application.properties,application.yml)中設置一個屬性debug=true,設置完成后再啟動Spring Boot 的入口類,就會在控制臺輸出有哪些Bean 已經完成了自動配置。

簡單的截了一些如下圖:

三、自動配置的原理分析

1.我們從入口類開始分析,我們都知道Spring Boot 項目一般會有一個入口類,這個入口類有一個很重要的特征就是加上了@SpringBootApplication注解。

@SpringBootApplication 是一個組合注解,如下:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan

其中有一個重要的注解@EnableAutoConfiguration,這個注解的作用就是用于啟用Spring Boot 的自動配置。

2.接著具體查看@EnableAutoConfiguration,其實它也是一個組合注解,如下:

@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class)

有一個注解@Import(EnableAutoConfigurationImportSelector.class),在這個注解中有一個導入自動配置的選擇器,用于導入自動配置的Bean。

下面就來分析這個EnableAutoConfigurationImportSelector都做了什么。

3.EnableAutoConfigurationImportSelector類繼承自AutoConfigurationImportSelector,在這個類中只有一個方法,用于判斷是否啟動了自動配置。

@Deprecated public class EnableAutoConfigurationImportSelectorextends AutoConfigurationImportSelector {@Overrideprotected boolean isEnabled(AnnotationMetadata metadata) {if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,true);}return true;}}

那么我們就來看看它的父類AutoConfigurationImportSelector。

4.在AutoConfigurationImportSelector類中有一個selectImports()方法,如下:

@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}try {AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = getAttributes(annotationMetadata);// 用于獲取自動配置的相關信息List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);configurations = removeDuplicates(configurations);configurations = sort(configurations, autoConfigurationMetadata);/*** 獲得移除的自動配置信息* 如果我們不想讓Spring Boot 自動配置一些Bean, 我們可以使用在入口類的注解中使用exclude 聲明* 比如:@SpringBootApplication(exclude = {DispatcherServlet.class})*/Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = filter(configurations, autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations, exclusions);return configurations.toArray(new String[configurations.size()]);}catch (IOException ex) {throw new IllegalStateException(ex);}}

我們主要查看上面方法中的getCandidateConfigurations(annotationMetadata, attributes)方法,

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes) {// 調用SpringFactoriesLoader 的loadFactoryNames() 方法,返回從類路徑下獲得自動配置相關的信息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;}

下面接著查看loadFactoryNames()方法,

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {// factoryClass = EnableAutoConfiguration.class,可以通過上一步查看String factoryClassName = factoryClass.getName();try {/*** FACTORIES_RESOURCE_LOCATION 是一個編譯器期量值為:"META-INF/spring.factories"* 用于獲得所有jar 包類路徑下的META-INF下的spring.factories 文件的URL*/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 properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));/*** 獲取EnableAutoConfiguration 類名在properties 中的值* 這些值對應的Bean 就是要添加到Spring 容器中的自動配置類*/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);}}

到這里就可知道Spring Boot 是如何實現自動配置的了,Spring Boot 會掃描到類路徑下的META-INF/spring.factories配置文件,把EnableAutoConfiguration對應的的Bean值添加到容器中。

5.接著我們就來看一下類路徑下META-INF/spring.factories配置文件,其中EnableAutoConfiguration對應的值都是有哪些。

下面是spring.factories配置文件中EnableAutoConfiguration對應的值,為了顯示的效果在這里只貼出一部分。我們可以發現一個規律,這些值一般都是以×××AutoConfiguration命名,每一個×××AutoConfiguration 都作為容器中的一個組件,被添加到IoC 容器中,從而實現Spring Boot 的自動配置。

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.CloudAutoConfiguration,\

四、總結

這篇博文簡單的分析了Spring Boot 自動配置的原理,給大家提供一個參考的方向,關于其中的一些具體細節,大家可以自己查看底層的源碼進行了解,希望本篇博文能夠為你提供幫助。

總結

以上是生活随笔為你收集整理的Spring Boot自动配置原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。