裝配 SpringBoot自動配置流程( 三 )


檢查是否有無效的排除類存在

  1. 1 configurations.removeAll(exclusions);
//檢查是否有無效的排除類存在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()) {//處理無效配置項 --> 報錯 IllegalStateException 無效狀態異常handleInvalidExcludes(invalidExcludes);}}-----------------------------------------------------------------------------------------/*下面方法是上面方法所調用的個別方法源碼,不深究者可以略過*/-----------------------------------------------------------------------------------------/** *ClassUtils.isPresent() 根據類名稱判斷是否存在并且可以加載 , 如果類或其依賴項之一不存在或無法加載返回false * param1 className 要檢查的類的名稱 * param2 classLoader 要使用的類加載器(如果為null , 表示默認的類加載器) */public static boolean isPresent(String className, @Nullable ClassLoader classLoader) {try {//forName(類名稱 , 類加載器) 用于替換Class.forName()方法, 并且還返回所提供名稱的類實例forName(className, classLoader);return true;}catch (IllegalAccessError err) {throw new IllegalStateException("Readability mismatch in inheritance hierarchy of class [" +className + "]: " + err.getMessage(), err);}catch (Throwable ex) {// Typically ClassNotFoundException or NoClassDefFoundError...return false;}}從自動配置項中刪除需要被排除的配置項
  1. 2 configurations.removeAll(exclusions);
/** *從自動配置候選項中刪除需要排除的配置項 * 集合A.removeAll(集合B);作用就是從集合A數據項中刪除掉集合B所包含的元素 */configurations.removeAll(exclusions);創建配置類過濾器對配置項進行篩選過濾
  1. configurations = getConfigurationClassFilter().filter(configurations);
//通過getConfigurationClassFilter()獲取所有AutoConfigurationImportFilter的實現類(對spring.factories進行過濾的類),而后調用filter方法對配置文件進行篩選,而后返回需要自動配置的類configurations = getConfigurationClassFilter().filter(configurations);-----------------------------------------------------------------------------------------/*下面方法是上面方法所調用的個別方法源碼,不深究者可以略過*/-----------------------------------------------------------------------------------------//獲取配置類過濾器private ConfigurationClassFilter getConfigurationClassFilter() {//this.configurationClassFilter當前類的配置類過濾器是不是為nullif (this.configurationClassFilter == null) {// 獲取AutoConfigurationImportFilter過濾器的實現類集合List<AutoConfigurationImportFilter> filters = getAutoConfigurationImportFilters();for (AutoConfigurationImportFilter filter : filters) {invokeAwareMethods(filter);//在監聽器注入是有描述 , 兩者使用的同一方法}//實例化配置類過濾器 ,根據 類加載器和過濾器實現類實例化配置類過濾器//ConfigurationClassFilter類內部含有類加載器和過濾器實現類集合的屬性this.configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);}//返回配置類過濾器return this.configurationClassFilter;}//getAutoConfigurationImportFilters(); 獲取AutoConfigurationImportFilter過濾器的實現類集合protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {/*** List<T>loadFacotries(Class<T> factoryType, @Nullable ClassLoader classLoader)* 使用給定的類加載器從{"META-INF/spring.factories"}加載并實例化指定過濾器工廠的實現類* 在結果返回之前會對結果集進行排序* param1 表示工廠的接口或者抽象類,-->生成其子類* param2 當前類的類加載器-->用于加載抽象類的實現類* return 返回指定接口或者抽象類的實現類List集合*///返回AutoConfigurationImportFilter實現類的集合return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader); }//configurations = getConfigurationClassFilter().filter(configurations);//過濾 自動配置項List<String> filter(List<String> configurations) {long startTime = System.nanoTime();//將將配置轉化為字符串數組String[] candidates = StringUtils.toStringArray(configurations);boolean skipped = false;for (AutoConfigurationImportFilter filter : this.filters) {//循環過濾條件與配置項進行一一匹配,剔除掉條件不成立的配置項boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);for (int i = 0; i < match.length; i++) {if (!match[i]) {candidates[i] = null;skipped = true;}}}//如果全都符合則直接返回配置項集合if (!skipped) {return configurations;}//創建結果集集合List<String> result = new ArrayList<>(candidates.length);for (String candidate : candidates) {//配置項不為null就添加到配置類中if (candidate != null) {result.add(candidate);}}//返回結果return result;} }

推薦閱讀