10、SpringBoot 源碼分析 - 自動配置深度分析三

SpringBoot 源碼分析 - 自動配置深度分析三

  • refresh和自動配置大致流程
  • AutoConfigurationImportSelector的getAutoConfigurationEntry獲取自動配置實體(重點)
    • AutoConfigurationImportSelector的getCandidateConfigurations獲取EnableAutoConfiguration類型的名字集合
    • AutoConfigurationImportSelector的removeDuplicates去重
    • AutoConfigurationImportSelector的getExclusions獲取要排除的
    • AutoConfigurationImportSelector的checkExcludedClasses檢查要排除的
    • AutoConfigurationImportSelector的filter過濾

refresh和自動配置大致流程

在這里插入圖片描述

AutoConfigurationImportSelector的getAutoConfigurationEntry獲取自動配置實體(重點)

前面講了那么多,都是為了這里啊,不然直接上來都不知道是怎么來的,我們來看看這個干了什么,別看就那么點,其實里面很復雜,簡單的說就是從我們初始化加載的所有的jar包下的META-INF/spring.factories屬性中找到org.springframework.boot.autoconfigure.EnableAutoConfiguration屬性,其實這個時候以及有緩存啦,前面初始化的時候已經全加載過了。然后進行去重,再獲取要排除的名字,檢查排除的類的合理性,然后排除,再進行條件類過濾,因為可能有些配置類缺少某些類就不能用了,觸發自動裝配導入事件,最后封裝成AutoConfigurationEntry返回。

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);//獲取自動裝配類configurations = removeDuplicates(configurations);//去重Set<String> exclusions = getExclusions(annotationMetadata, attributes);//獲取要排除的checkExcludedClasses(configurations, exclusions);//檢查要排除的configurations.removeAll(exclusions);//排除configurations = filter(configurations, autoConfigurationMetadata);//過濾fireAutoConfigurationImportEvents(configurations, exclusions);//觸發導入事件return new AutoConfigurationEntry(configurations, exclusions);}

主要自動配置類都在這里,當然我們可以自定義,后面我們會自定義一個:
在這里插入圖片描述

AutoConfigurationImportSelector的getCandidateConfigurations獲取EnableAutoConfiguration類型的名字集合

這個代碼我們前面很熟悉啊,就不多說了,從緩存中加載對應EnableAutoConfiguration類型的類名字,最終加載了124個,好多啊,沒關系,后面過濾就沒那么多了。

在這里插入圖片描述

AutoConfigurationImportSelector的removeDuplicates去重

這個很巧妙,放進Set里又拿出來放進List里:

	protected final <T> List<T> removeDuplicates(List<T> list) {return new ArrayList<>(new LinkedHashSet<>(list));}

AutoConfigurationImportSelector的getExclusions獲取要排除的

其實就是從注解屬性的excludeexcludeName獲取,當然還有個環境配置屬性spring.autoconfigure.exclude也可以,就是說可以在yml或者propertise里配啦,其他就不多說了。
在這里插入圖片描述
在這里插入圖片描述

AutoConfigurationImportSelector的checkExcludedClasses檢查要排除的

其實就是看下要排除的在不在自動配置集合里,有不在的就報異常,可能要排除的并不是自動配置的類,表示無效排除:

	private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {List<String> invalidExcludes = new ArrayList<>(exclusions.size());for (String exclusion : exclusions) {if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) {invalidExcludes.add(exclusion);//不在自動配置類里,還要排除的,屬于無效排除,要拋異常}}if (!invalidExcludes.isEmpty()) {handleInvalidExcludes(invalidExcludes);}}protected void handleInvalidExcludes(List<String> invalidExcludes) {StringBuilder message = new StringBuilder();for (String exclude : invalidExcludes) {message.append("\t- ").append(exclude).append(String.format("%n"));}throw new IllegalStateException(String.format("The following classes could not be excluded because they are not auto-configuration classes:%n%s",message));}

AutoConfigurationImportSelector的filter過濾

這里會獲取過濾器,其實就是OnClassConditionOnWebApplicationConditionOnBeanCondition這幾個條件,他會去配置類的注解上查找相應的條件類是否存在,不存在就會被過濾掉,過濾的時候可能會開啟線程,幫助一起處理,因為配置類數量多。如果多核的話,會用啟動一個線程去分擔一半數量的檢查,會判斷條件類是否能加載到,不能就被過濾掉了,如果用多個線程可能效果不太好,spring團隊應該做過實驗,2個最好。

private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {long startTime = System.nanoTime();// 轉換自動配置類的List集合為String數組String[] candidates = StringUtils.toStringArray(configurations);// 存儲最終的匹配結果,和candidates數組索引位置一一對應,true代表最終需要// 自動引入,false代表不需要自動引入boolean[] skip = new boolean[candidates.length];boolean skipped = false;// <AutoConfigurationImportSelector#filter_1>見詳細講解for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {// <AutoConfigurationImportSelector#filter_2>見詳細講解invokeAwareMethods(filter);// <AutoConfigurationImportSelector#filter_3>見詳細講解boolean[] match = filter.match(candidates, autoConfigurationMetadata);// 循環當前的自動引入過濾器過濾結果,并記錄過濾結果,用于后續邏輯過濾使用for (int i = 0; i < match.length; i++) {if (!match[i]) {skip[i] = true;candidates[i] = null;skipped = true;}}}// 當沒有需要過濾的自動配置類時,會進if直接返回,否則執行后續邏輯,通過布爾數組進行過濾if (!skipped) {return configurations;}// 存儲過濾后需要自動配置的類List<String> result = new ArrayList<>(candidates.length);for (int i = 0; i < candidates.length; i++) {// 如果當前位置為fasle則說明不需要跳過,則添加到最終結果中if (!skip[i]) {result.add(candidates[i]);}}// <AutoConfigurationImportSelector#filter_4>見詳細講解if (logger.isTraceEnabled()) {int numberFiltered = configurations.size() - result.size();logger.trace("Filtered " + numberFiltered + " auto configuration class in "+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");}// 返回結果,不知道為什么要再重新new一個return new ArrayList<>(result);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13846.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13846.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13846.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android中JVM內存回收機制

文章目錄 分代收集算法&#xff1a;新生代&#xff08;Young Generation&#xff09;老年代&#xff08;Old Generation&#xff09; 垃圾回收器&#xff1a;JVM常見三大回收算法&#xff1a;Mark-Sweep(標記清除)優點:缺點: 復制算法優點&#xff1a;缺點&#xff1a; Mark-Co…

ubuntu下交叉編譯安卓FFmpeg 和 官方指導鏈接

將之前的編譯方法在此記錄 Linux系統&#xff1a;Ubuntu 18.04.6 LTS 交叉編譯工具鏈&#xff1a;gcc-aarch64-linux-gnu gaarch64-linux-gnu ffmpeg版本&#xff1a;5.1.3 1.下載源碼 ffmpeg官網&#xff1a;https://ffmpeg.org/download.html#releases 下載完成后&#x…

Edge瀏覽器“此頁存在問題”解決思路

Edge瀏覽器顯示“此頁存在問題”解決思路 大家平時使用Edge瀏覽器時&#xff0c;是否和我一樣會突然出現“此頁存在問題”的情況&#xff1f; 經過百度查詢后我找了一種情況和解決辦法&#xff0c;能夠大大減少這類問題的出現。出現“此頁存在問題”可能是因為之前使用過軟件…

每天一個數據分析題(三百四十一)

如何獲取更多優質流量是電商行業中重要課題&#xff0c;下列哪些屬于流量類指標 A. 平均訪問深度 B. 跳失次數 C. 瀏覽量 D. 客單價 數據分析認證考試介紹&#xff1a;點擊進入 題目來源于CDA模擬題庫 點擊此處獲取答案

Linux基礎命令[27]-gpasswd

文章目錄 1. gpasswd 命令說明2. gpasswd 命令語法3. gpasswd 命令示例3.1 不加參數3.2 -a&#xff08;將用戶加入組&#xff09;3.3 -d&#xff08;從組中刪除用戶&#xff09;3.4 -r&#xff08;刪除組密碼&#xff09;3.5 -M&#xff08;多個用戶一起加入組&#xff09;3.6 …

React中 將UI 視為樹

當 React 應用程序逐漸成形時&#xff0c;許多組件會出現嵌套。那么 React 是如何跟蹤應用程序組件結構的&#xff1f; React 以及許多其他 UI 庫&#xff0c;將 UI 建模為樹。將應用程序視為樹對于理解組件之間的關系以及調試性能和狀態管理等未來將會遇到的一些概念非常有用。…

Python教程:使用Python和PyQt編寫進制轉換器工具

1.介紹 在現代計算中&#xff0c;進制轉換是一項常見且重要的任務。為了簡化這個過程&#xff0c;我們也可以利用Python和PyQt自己寫一個直觀且易于使用的進制轉換器工具。這個工具將支持二進制、八進制、十進制和十六進制的相互轉換&#xff0c;并提供良好的用戶界面和交互體…

Java設計模式(23種設計模式 重點介紹一些常用的)

創建型模式&#xff0c;共五種&#xff1a;工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。結構型模式&#xff0c;共七種&#xff1a;適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。行為型模式&#xff0c;共十一種&#xff1a;…

MySQL---函數與約束

目錄 一、函數 1. 字符串函數 2. 數值函數 3. 日期函數 4. 流程函數 5. 總結 二、約束 1. 概述 2. 約束演示 3. 外鍵約束 3.1 添加外鍵 3.2 刪除外鍵 3.3 外鍵刪除更新行為 4. 總結 一、函數 1. 字符串函數 命令如下所示&#xff1a; -- concat select concat("Hel…

蘋果CMS:如何去掉首頁幫助提示信息

首先我們安裝好蘋果CMS&#xff0c;未安裝的可以參考蘋果cms&#xff1a;介紹及安裝 安裝好之后我們需要進入模版設置&#xff0c;可能對于剛剛接觸CMS框架的朋友是不清楚地址的&#xff1a; https://www.yourweb.com/admin_login.php/admin/mxpro/mxproset 其中【yourweb】…

愛設計AiPPT.cn趙充:營銷工作的AI進化

愛設計&AiPPT.cn是一家 AIGC 數字科技企業&#xff0c;致力于打造「下一代個人與組織的 Ai 工作站」 。目前旗下產品包括AiPPT.cn、愛設計AIGC 內容中臺、365 編輯器、愛設計在線設計工具、AiH5 等超過 10 余款應用 AI 能力的內容創作工具。日前&#xff0c;愛設計&AiP…

python的協程異步

參考資料 https://blog.csdn.net/qq_43380180/article/details/111573642?spm1001.2014.3001.5506 協程的概念 指的是在一個線程中&#xff0c;可以在某個地方掛起的特殊函數&#xff0c;并且可以重新在掛起處繼續運行。協程不是進程&#xff0c;也不是線程。 進程 VS 線程…

dcache-android框架中的設計模式詳解

引言&#xff1a;孤獨的人喜歡深夜&#xff0c;多情的人喜歡黃昏。幸福的人喜歡陽光&#xff0c;傷心的人偏愛風雨。 眾所周知&#xff0c;dcache-android是本人一行一行代碼手寫出來的Android數據緩存框架&#xff0c;寫了好幾年了&#xff0c;雖然不是每天寫&#xff0c;但一…

【go從入門到精通】精通并發編程-使用扇入扇出提升多個通道之間傳遞數據的效率

在并發編程領域,Golang 作為一種擅長處理并發的編程語言而脫穎而出。 Go 并發模型的一個關鍵組件是通道,它允許 goroutine 進行通信并同步其工作。在這里,我們將探討在 Go 中的多個通道之間傳遞數據的技術。當需要協調不同 goroutine 之間的工作并管理數據流時,這非常有用。…

TypeScript-類型斷言

類型斷言 當開發者比TS本身更清楚當前的類型是什么&#xff0c;可以使用斷言(as)讓類型更加精確和具體 const _link document.getElementById(link) console.log(_link.href) // 出錯了&#xff0c;如下圖 const _link document.getElementById(link) as HTMLAnchorElement…

【三數之和】python,排序+雙指針

暴力搜索3次方的時間復雜度&#xff0c;大抵超時 遇到不會先排序 排序雙指針 上題解 照做 class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:res[]nlen(nums)#排序降低復雜度nums.sort()k0#留兩個位置給雙指針i,jfor k in range(n-2):if nums[k]…

【再探】Java—泛型

Java 泛型本質是參數化類型&#xff0c;可以用在類、接口和方法的創建中。 1 “擦除式”泛型 Java的“擦除式”的泛型實現一直受到開發者的詬病。 “擦除式”的實現幾乎只需要在Javac編譯器上做出改進即可&#xff0c;不要改動字節碼、虛擬機&#xff0c;也保證了以前沒有使…

光伏電站在線監測智能診斷系統:開啟無人值守新紀元

光伏電站在線監測智能診斷系統&#xff1a;開啟無人值守新紀元 大家都知道光伏電站是通過汲取著太陽的光芒&#xff0c;為人類提供源源不斷的電能源。然而&#xff0c;隨著光伏電站規模的擴大和復雜性的增加&#xff0c;如何有效提高發電效率、減少人工維護成本&#xff0c;實…

YOLOV5算法多目標檢測系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 隨著計算機視覺技術的飛速發展&#xff0c;目標檢測已成為許多實際應用場景中的關鍵技術&…

AWS存儲之 Storage Gateway

AWS Storage Gateway是一項混合存儲服務&#xff0c;它允許您在本地環境和AWS云之間無縫地集成存儲解決方案。它提供了一種簡單、安全地方式&#xff0c;讓您可以將本地應用程序連接到云存儲服務&#xff0c;如Amazon S3、Amazon Glacier、Amazon EBS等。 比如一個公司如果想將…