SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼_第1頁
SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼_第2頁
SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼_第3頁
SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼_第4頁
SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第SpringBoot深入分析AutoConfigurationImportFilter自動化條件配置源碼目錄1.AutoConfigurationImportFilter的作用2.AutoConfigurationImportFilterUML類圖說明3.FilteringSpringBootCondition抽象類4.AutoConfigurationImportSelector類5.總結(jié)

1.AutoConfigurationImportFilter的作用

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

AutoConfigurationImportFilter的源碼:

@FunctionalInterface

publicinterfaceAutoConfigurationImportFilter{

*Applythefiltertothegivenauto-configurationclasscandidates.

*@paramautoConfigurationClassestheauto-configurationclassesbeingconsidered.

*Thisarraymaycontain{@codenull}elements.Implementationsshouldnotchangethe

*valuesinthisarray.

*@paramautoConfigurationMetadataaccesstothemeta-datageneratedbythe

*auto-configureannotationprocessor

*@returnabooleanarrayindicatingwhichoftheauto-configurationclassesshould

*beimported.Thereturnedarraymustbethesamesizeastheincoming

*{@codeautoConfigurationClasses}parameter.Entriescontaining{@codefalse}will

*notbeimported.

boolean[]match(String[]autoConfigurationClasses,AutoConfigurationMetadataautoConfigurationMetadata);

}

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

2.AutoConfigurationImportFilterUML類圖說明

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

3.FilteringSpringBootCondition抽象類

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

abstractclassFilteringSpringBootConditionextendsSpringBootCondition

implementsAutoConfigurationImportFilter,BeanFactoryAware,BeanClassLoaderAware{

//bean工廠

privateBeanFactorybeanFactory;

//bean加載器

privateClassLoaderbeanClassLoader;

@Override

publicboolean[]match(String[]autoConfigurationClasses,AutoConfigurationMetadataautoConfigurationMetadata){

//獲取條件化判斷報告,用于記錄處理結(jié)果

ConditionEvaluationReportreport=ConditionEvaluationReport.find(this.beanFactory);

//獲取具體匹配處理結(jié)果,由抽象方法getOutcomes負責具體實現(xiàn)

ConditionOutcome[]outcomes=getOutcomes(autoConfigurationClasses,autoConfigurationMetadata);

boolean[]match=newboolean[outcomes.length];

//遍歷條件處理結(jié)果

for(inti=0;ioutcomes.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]);

returnmatch;

}

先獲取ConditionEvaluationReport對象,用于記錄處理結(jié)果。調(diào)用getOutcomes方法,這個一個抽象方法,返回匹配處理結(jié)果,由上面UML圖中的OnXXXCondition等類負責具體實現(xiàn)。接下來創(chuàng)建match數(shù)組,布爾值標記處理結(jié)果。下面還會調(diào)用logOutcome方法,做日志打印處理。調(diào)用recordConditionEvaluation,記錄匹配結(jié)果。

除了match方法,F(xiàn)ilteringSpringBootCondition下還有個filter方法。

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

protectedListStringfilter(CollectionStringclassNames,ClassNameFilterclassNameFilter,

ClassLoaderclassLoader){

//校驗,為空判斷

if(CollectionUtils.isEmpty(classNames)){

returnCollections.emptyList();

//記錄match匹配結(jié)果

ListStringmatches=newArrayList(classNames.size());

//遍歷處理

for(Stringcandidate:classNames){

//從指定的classLoader中加載class,再根據(jù)ClassNameFilter類型,返回最終結(jié)果

if(classNameFilter.matches(candidate,classLoader)){

matches.add(candidate);

returnmatches;

}

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

我們再看下ClassNameFilter的源碼:

protectedenumClassNameFilter{

//兩種類型,當前存在優(yōu)先,如果classLoader中能夠加載指定類,返回true

PRESENT{

@Override

publicbooleanmatches(StringclassName,ClassLoaderclassLoader){

returnisPresent(className,classLoader);

//缺失優(yōu)先規(guī)則,即便在classLoader中能夠加載指定類,也是返回false

MISSING{

@Override

publicbooleanmatches(StringclassName,ClassLoaderclassLoader){

return!isPresent(className,classLoader);

//抽象方法,有子類負責具體匹配邏輯實現(xiàn)

publicabstractbooleanmatches(StringclassName,ClassLoaderclassLoader);

//判斷指定的類,是否能夠通過指定的classLoader加載

publicstaticbooleanisPresent(StringclassName,ClassLoaderclassLoader){

if(classLoader==null){

classLoader=ClassUtils.getDefaultClassLoader();

try{

forName(className,classLoader);

returntrue;

catch(Throwableex){

returnfalse;

//類的加載處理

privatestaticClassforName(StringclassName,ClassLoaderclassLoader)throwsClassNotFoundException{

if(classLoader!=null){

returnclassLoader.loadClass(className);

returnClass.forName(className);

}

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

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

4.AutoConfigurationImportSelector類

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

publicclassAutoConfigurationImportSelectorimplementsDeferredImportSelector,BeanClassLoaderAware,

ResourceLoaderAware,BeanFactoryAware,EnvironmentAware,Ordered{

privateListStringfilter(ListStringconfigurations,AutoConfigurationMetadataautoConfigurationMetadata){

longstartTime=System.nanoTime();

//根據(jù)配置上下文,獲取所有需要處理的自動化配置類信息,也就是所有的auotconfigration實現(xiàn)類

String[]candidates=StringUtils.toStringArray(configurations);

boolean[]skip=newboolean[candidates.length];

booleanskipped=false;

//遍歷處理,通過getAutoConfigurationImportFilters方法,獲取springFactores中的選擇處理器,包含OnClassCondition、OnWebApplicationCondition和OnBeanCondition。

for(AutoConfigurationImportFilterfilter:getAutoConfigurationImportFilters()){

//填充filter信息

invokeAwareMethods(filter);

//獲取filter的匹配結(jié)果

boolean[]match=filter.match(candidates,autoConfigurationMetadata);

for(inti=0;imatch.length;i++){

if(!match[i]){

//如果沒有匹配,skip標記為true

skip[i]=true;

//清除該auotconfigration記錄信息

candidates[i]=null;

skipped=true;

if(!skipped){

//完全匹配,直接返回configurations數(shù)據(jù)

returnconfigurations;

ListStringresult=newArrayList(candidates.length);

for(inti=0;icandidates.length;i++){

if(!skip[i]){

//記錄需要處理的自動化配置信息

result.add(candida

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論