最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot 深入分析AutoConfigurationImportFilter自動(dòng)化條件配置源碼

 更新時(shí)間:2022年07月13日 09:33:51   作者:麥神-mirson  
這篇文章主要分析了Spring Boot AutoConfigurationImportFilter自動(dòng)化條件配置源碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

1. AutoConfigurationImportFilter的作用

之前講解了SpringBoot的Conditional的自動(dòng)化條件配置,我們分析了內(nèi)部是如何具體實(shí)現(xiàn),在整個(gè)實(shí)現(xiàn)當(dāng)中, 還有一個(gè)很重要的接口, AutoConfigurationImportFilter是它的前置調(diào)用, 它是一個(gè)過濾器接口,我們?cè)僮錾钊胙芯浚?看下是如何控制處理這么多條件注解, 又是怎樣過濾處理的,從性能效率又做了哪些處理?

AutoConfigurationImportFilter的源碼:

@FunctionalInterface
public interface AutoConfigurationImportFilter {
	/**
	 * Apply the filter to the given auto-configuration class candidates.
	 * @param autoConfigurationClasses the auto-configuration classes being considered.
	 * This array may contain {@code null} elements. Implementations should not change the
	 * values in this array.
	 * @param autoConfigurationMetadata access to the meta-data generated by the
	 * auto-configure annotation processor
	 * @return a boolean array indicating which of the auto-configuration classes should
	 * be imported. The returned array must be the same size as the incoming
	 * {@code autoConfigurationClasses} parameter. Entries containing {@code false} will
	 * not be imported.
	 */
	boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata);
}

從說明可以看到,該類主要功能是過濾那些在spring.factories配置文件中定義的自動(dòng)化配置項(xiàng), 還有一個(gè)重要作用是在自動(dòng)化配置類的字節(jié)碼加載之前進(jìn)行攔截過濾,提升處理效率, 節(jié)省資源開銷。

2. AutoConfigurationImportFilter UML類圖說明

從圖中可以看到, AutoConfigurationImportFilter一共有三個(gè)實(shí)現(xiàn)類(OnBeanCondition、OnClasssCondition、OnWebApplicationCondition),三個(gè)類都是通過FilteringSpringBootCondition抽象父類間接實(shí)現(xiàn),AutoConfigurationImportFilter在所有OnXXXCondition條件注解類的上層,這樣大概就能看出它們的調(diào)用棧的關(guān)聯(lián)關(guān)系, 經(jīng)過研究代碼, Spring Boot 會(huì)先調(diào)用AutoConfigurationImportFilter的match方法做過濾處理, 后面再通過loadBeanDefinitions觸發(fā)Condition的matches方法做條件判斷。

3. FilteringSpringBootCondition抽象類

FilteringSpringBootCondition是一個(gè)抽象類, 它繼承SpringBootCondition,實(shí)現(xiàn)AutoConfigurationImportFilter的match接口, 內(nèi)部調(diào)用抽象方法getOutcomes負(fù)責(zé)具體的過濾邏輯處理。

abstract class FilteringSpringBootCondition extends SpringBootCondition
		implements AutoConfigurationImportFilter, BeanFactoryAware, BeanClassLoaderAware {
	// bean 工廠
	private BeanFactory beanFactory;
	// bean 加載器
	private ClassLoader beanClassLoader;
    // 
	@Override
	public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {
		// 獲取條件化判斷報(bào)告, 用于記錄處理結(jié)果
		ConditionEvaluationReport report = ConditionEvaluationReport.find(this.beanFactory);
		// 獲取具體匹配處理結(jié)果, 由抽象方法getOutcomes負(fù)責(zé)具體實(shí)現(xiàn)
		ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses, autoConfigurationMetadata);
		boolean[] match = new boolean[outcomes.length];
		// 遍歷條件處理結(jié)果
		for (int i = 0; i < outcomes.length; i++) {
			match[i] = (outcomes[i] == null || outcomes[i].isMatch());
			if (!match[i] && outcomes[i] != null) {
				// 日志打印記錄
				logOutcome(autoConfigurationClasses[i], outcomes[i]);
				if (report != null) {
					// 記錄匹配處理結(jié)果
					report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);
				}
			}
		}
		return match;
	}
	...
}
  • 先獲取ConditionEvaluationReport對(duì)象, 用于記錄處理結(jié)果。
  • 調(diào)用getOutcomes方法, 這個(gè)一個(gè)抽象方法, 返回匹配處理結(jié)果, 由上面UML圖中的OnXXXCondition等類負(fù)責(zé)具體實(shí)現(xiàn)。
  • 接下來創(chuàng)建match數(shù)組, 布爾值標(biāo)記處理結(jié)果。
  • 下面還會(huì)調(diào)用logOutcome方法, 做日志打印處理。調(diào)用recordConditionEvaluation, 記錄匹配結(jié)果。

除了match方法, FilteringSpringBootCondition下還有個(gè) filter 方法。

Filter方法, protected修飾, 實(shí)際上會(huì)由OnXXXCondition的getOutcomes方法調(diào)用, 從UML關(guān)系圖可以看到, 實(shí)際是由子類處理邏輯實(shí)現(xiàn)過程中調(diào)用。

protected List<String> filter(Collection<String> classNames, ClassNameFilter classNameFilter,
			ClassLoader classLoader) {
    	// 校驗(yàn), 為空判斷
		if (CollectionUtils.isEmpty(classNames)) {
			return Collections.emptyList();
		}
        // 記錄match匹配結(jié)果
		List<String> matches = new ArrayList<>(classNames.size());
        // 遍歷處理
		for (String candidate : classNames) {
            // 從指定的classLoader中加載class,再根據(jù)ClassNameFilter類型, 返回最終結(jié)果
			if (classNameFilter.matches(candidate, classLoader)) {
				matches.add(candidate);
			}
		}
		return matches;
	}

從源碼可以看到,先做簡(jiǎn)單的為空判斷, 具體則是通過classNameFilter的match方法做處理。

我們?cè)倏聪翪lassNameFilter的源碼:

protected enum ClassNameFilter {
		// 兩種類型, 當(dāng)前存在優(yōu)先, 如果classLoader中能夠加載指定類, 返回true
		PRESENT {
			@Override
			public boolean matches(String className, ClassLoader classLoader) {
				return isPresent(className, classLoader);
			}
		},
		// 缺失優(yōu)先規(guī)則, 即便在classLoader中能夠加載指定類, 也是返回false
		MISSING {
			@Override
			public boolean matches(String className, ClassLoader classLoader) {
				return !isPresent(className, classLoader);
			}
		};
    	// 抽象方法, 有子類負(fù)責(zé)具體匹配邏輯實(shí)現(xiàn) 
		public abstract boolean matches(String className, ClassLoader classLoader);
    	// 判斷指定的類, 是否能夠通過指定的classLoader加載
		public static boolean isPresent(String className, ClassLoader classLoader) {
			if (classLoader == null) {
				classLoader = ClassUtils.getDefaultClassLoader();
			}
			try {
				forName(className, classLoader);
				return true;
			}
			catch (Throwable ex) {
				return false;
			}
		}
		// 類的加載處理
		private static Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
			if (classLoader != null) {
				return classLoader.loadClass(className);
			}
			return Class.forName(className);
		}
	}

從中可以看出, 這里面有兩種形式判斷,一種是PRESENT, 另外一種是MISSING, 兩種類型為相反邏輯, 通過isPresent方法做判斷,里面則根據(jù)ClassLoader, 如果不為空, 則加載目標(biāo)CLASS,處理沒有報(bào)錯(cuò), 則返回true值。

講到這里, Filter的作用是什么?ClassNameFilter兩種類型有什么意義? 我們舉個(gè)例子說明, @ConditionalOnClass和@ConditionalOnMissingClass兩個(gè)注解,判斷條件是指定的CLASS是否存在。 如果采用ConditionalOnClass注解, 那么采用PRESENT存在優(yōu)先規(guī)則, 如果采用ConditionalOnMissingClass注解, 那么采用MISSING缺失優(yōu)先規(guī)則。

4. AutoConfigurationImportSelector類

再分析一下AutoConfigurationImportSelector這個(gè)類, 這是一個(gè)自動(dòng)配置導(dǎo)入選擇處理器,在AutoConfigurationImportFilter的match方法之前調(diào)用, 是屬于上層調(diào)用。先由springFactores加載選擇處理器, 主要包含OnClassCondition、OnWebApplicationCondition和OnBeanCondition等, 再做具體的條件判斷處理。 我們了解下它的處理邏輯:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
		long startTime = System.nanoTime();
    	// 根據(jù)配置上下文, 獲取所有需要處理的自動(dòng)化配置類信息, 也就是所有的auotconfigration實(shí)現(xiàn)類
		String[] candidates = StringUtils.toStringArray(configurations);
		boolean[] skip = new boolean[candidates.length];
		boolean skipped = false;
    	// 遍歷處理, 通過getAutoConfigurationImportFilters方法, 獲取springFactores中的選擇處理器, 包含OnClassCondition、OnWebApplicationCondition和OnBeanCondition。
		for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
            // 填充filter信息
			invokeAwareMethods(filter);
            // 獲取filter的匹配結(jié)果
			boolean[] match = filter.match(candidates, autoConfigurationMetadata);
			for (int i = 0; i < match.length; i++) {
				if (!match[i]) {
                    // 如果沒有匹配, skip標(biāo)記為true
					skip[i] = true;
                    // 清除該auotconfigration記錄信息
					candidates[i] = null;
					skipped = true;
				}
			}
		}
		if (!skipped) {
            // 完全匹配, 直接返回configurations數(shù)據(jù)
			return configurations;
		}
		List<String> result = new ArrayList<>(candidates.length);
		for (int i = 0; i < candidates.length; i++) {
			if (!skip[i]) {
                // 記錄需要處理的自動(dòng)化配置信息
				result.add(candidates[i]);
			}
		}
		if (logger.isTraceEnabled()) {
            // 是否需要日志打印追蹤
			int numberFiltered = configurations.size() - result.size();
			logger.trace("Filtered " + numberFiltered + " auto configuration class in "
					+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
		}
		return new ArrayList<>(result);
	}
	...
}

可以看到, 通過getAutoConfigurationImportFilters()加載過濾器, 在調(diào)用過濾器的match執(zhí)行邏輯處理。條件匹配處理完成之后, 如果完全匹配, 則直接返回Configuration信息, 否則, 記錄需要處理的自動(dòng)化配置信息并做返回。 Configuration信息實(shí)際就是Spring Boot內(nèi)置的一百多個(gè)自動(dòng)化配置類:

這里也就是根據(jù)條件去過濾判斷, 哪些AutoConfiguration符合規(guī)則, 哪些不符合規(guī)則, 只有符合規(guī)則的自動(dòng)化配置類才會(huì)進(jìn)入加載流程,實(shí)現(xiàn)對(duì)應(yīng)的組件功能。

5. 總結(jié)

AutoConfigurationImportFilter是Spring Boot條件化注解的核心過濾器接口,這個(gè)類在啟動(dòng)的時(shí)候通過SPI機(jī)制實(shí)現(xiàn),在Spring Boot的條件化配置中會(huì)進(jìn)行回調(diào). 基于Conditional的自動(dòng)化配置主要流程就分析到這里, 細(xì)節(jié)上就不再贅述, 大家有空可以再跟蹤源碼深入研究,了解更為細(xì)節(jié)的自動(dòng)化配置的處理邏輯。

到此這篇關(guān)于Spring Boot 深入分析AutoConfigurationImportFilter自動(dòng)化條件配置源碼的文章就介紹到這了,更多相關(guān)Spring Boot AutoConfigurationImportFilter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)日歷效果的示例代碼

    java實(shí)現(xiàn)日歷效果的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用java實(shí)現(xiàn)打印某年全部的日歷信息,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • 通過實(shí)例解析spring對(duì)象生命周期

    通過實(shí)例解析spring對(duì)象生命周期

    這篇文章主要介紹了通過實(shí)例解析spring對(duì)象生命周期,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼兩種解決方式

    Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼兩種解決方式

    jar包啟動(dòng),今天java開發(fā)過來找,說jar包啟動(dòng)日志是亂碼,這篇文章主要給大家介紹了關(guān)于Java運(yùn)行時(shí)jar終端輸出的中文日志亂碼的兩種解決方式,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Java實(shí)現(xiàn)簡(jiǎn)單聊天機(jī)器人

    Java實(shí)現(xiàn)簡(jiǎn)單聊天機(jī)器人

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單聊天機(jī)器人,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java使用flyway實(shí)現(xiàn)腳本自動(dòng)化的方法詳解

    Java使用flyway實(shí)現(xiàn)腳本自動(dòng)化的方法詳解

    Flyway是一個(gè)開源的數(shù)據(jù)庫(kù)版本控制工具,主要用于管理數(shù)據(jù)庫(kù)的版本和變更,它可以自動(dòng)化地將數(shù)據(jù)庫(kù)遷移到不同的版本,同時(shí)支持多種數(shù)據(jù)庫(kù)類型,本文給大家介紹了如何使用flyway實(shí)現(xiàn)腳本自動(dòng)化,需要的朋友可以參考下
    2023-10-10
  • 關(guān)于Java中的可見性和有序性問題

    關(guān)于Java中的可見性和有序性問題

    這篇文章主要介紹了關(guān)于Java中的可見性和有序性問題,Java在誕生之初就支持多線程,自然也有針對(duì)這三者的技術(shù)方案,今天就學(xué)習(xí)一下Java如何解決其中的可見性和有序性導(dǎo)致的問題,需要的朋友可以參考下
    2023-08-08
  • Spring Cloud Gateway全局異常處理的方法詳解

    Spring Cloud Gateway全局異常處理的方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring Cloud Gateway全局異常處理的相關(guān)資料,需要的朋友可以參考下
    2018-10-10
  • @PathVariable注解,讓spring支持參數(shù)帶值功能的案例

    @PathVariable注解,讓spring支持參數(shù)帶值功能的案例

    這篇文章主要介紹了@PathVariable注解,讓spring支持參數(shù)帶值功能的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • IDEA打包應(yīng)用程序的教程圖解

    IDEA打包應(yīng)用程序的教程圖解

    這篇文章主要介紹了IDEA打包應(yīng)用程序的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Spring Boot配置讀取實(shí)現(xiàn)方法解析

    Spring Boot配置讀取實(shí)現(xiàn)方法解析

    這篇文章主要介紹了Spring Boot配置讀取實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論

永丰县| 石首市| 三台县| 碌曲县| 胶州市| 翁源县| 沾化县| 普洱| 乌拉特后旗| 舒兰市| 武宣县| 通化市| 囊谦县| 陕西省| 饶平县| 华宁县| 宁河县| 渝北区| 新安县| 海门市| 遂宁市| 芒康县| 阿拉善右旗| 清丰县| 常州市| 岗巴县| 阜宁县| 余姚市| 共和县| 沙坪坝区| 清河县| 会泽县| 乌兰察布市| 邢台县| 东至县| 手机| 来安县| 湘阴县| 突泉县| 阳泉市| 广饶县|