亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot中getSpringFactoriesInstances源碼的示例分析

發布時間:2021-11-24 17:44:25 來源:億速云 閱讀:201 作者:小新 欄目:大數據

這篇文章主要介紹了springboot中getSpringFactoriesInstances源碼的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

 

一、概述及流程圖

在springboot啟動過程中,getSpringFactoriesInstances這個方法很重要,啟動的時候使用該方法從classpath上所有jar包中找出對應的META-INF/spring.factorys屬性文件,并將其中的初始化器和監聽器加載并實例化,應用于更進一步的初始化工作。其工作流程圖如下:

springboot中getSpringFactoriesInstances源碼的示例分析  
image
 

二、源碼解析

讓我們跟著流程圖和時序圖一步步窺視其中的奧妙:

springboot中getSpringFactoriesInstances源碼的示例分析  
image
  1. 調用getSpringFactoriesInstances()方法
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
 //資源加載器
 this.resourceLoader = resourceLoader;
 //斷言,傳入參數不能為空,即必須傳入啟動類
 Assert.notNull(primarySources, "PrimarySources must not be null");
 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
 //通過類路徑推斷服務類型
 this.webApplicationType = WebApplicationType.deduceFromClasspath();
 //1.加載初始化器并實例化,10.并賦值給initializers
 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
 //同上,監聽器
 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
 //推斷應用主類
 this.mainApplicationClass = deduceMainApplicationClass();
}
 
  1. 獲取類加載器和調用loadFactoryNames()方法及對返回結果進行初始化以及排序
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
 return getSpringFactoriesInstances(type, new Class<?>[] {});
}

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
 //2. 獲取類加載器
 ClassLoader classLoader = getClassLoader();
 // Use names and ensure unique to protect against duplicates
 //3. 調用loadFactoryNames方法,并使用set對其返回結果進行去重處理
 Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
 //9. 實例化初始化器
 List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
 //9. 對實例化的結果進行排序
 AnnotationAwareOrderComparator.sort(instances);
 return instances;
}

//該方法主要是通過反射實例化初始化器
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
   ClassLoader classLoader, Object[] args, Set<String> names) {
  List<T> instances = new ArrayList<>(names.size());
  for (String name : names) {
   try {
    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
    Assert.isAssignable(type, instanceClass);
    Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
    T instance = (T) BeanUtils.instantiateClass(constructor, args);
    instances.add(instance);
   }
   catch (Throwable ex) {
    throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
   }
  }
  return instances;
 }
 
  1. 查詢緩存和讀取META-INFO/spring.factorys文件key-value值,并對value值進行處理
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
  String factoryClassName = factoryClass.getName();
  // 返回初始化器的value值
  return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
 }

 private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
  MultiValueMap<String, String> result = //查詢緩存,如果有就返回,沒有就加載
  cache.get(classLoader);
  if (result != null) {
   return result;
  }

  try {
      //通過類加載器加載所有jar包中包含META-INFO/spring.factorys的文件資源路徑
   Enumeration<URL> urls = (classLoader != null ?
     classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
     ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
   result = new LinkedMultiValueMap<>();
   while (urls.hasMoreElements()) {
    URL url = urls.nextElement();
    UrlResource resource = new UrlResource(url);
    //實例化properties對象,并加載路徑中的spring.factorys文件內容
    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
    for (Map.Entry<?, ?> entry : properties.entrySet()) {
     String factoryClassName = ((String)
     //獲取key值
     entry.getKey()).trim();
     //對value值進行都好拆分處理
     for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
        //將key和value值存入result中 result.add(factoryClassName, factoryName.trim());
     }
    }
   }
   //將結果存入緩存
   cache.put(classLoader, result);
   return result;
  }
  catch (IOException ex) {
   throw new IllegalArgumentException("Unable to load factories from location [" +
     FACTORIES_RESOURCE_LOCATION + "]", ex);
  }
 }

感謝你能夠認真閱讀完這篇文章,希望小編分享的“springboot中getSpringFactoriesInstances源碼的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

酉阳| 大竹县| 沿河| 滦平县| 嘉义县| 措美县| 濉溪县| 原平市| 祁连县| 密山市| 东兴市| 民丰县| 东至县| 曲麻莱县| 泸定县| 贵港市| 简阳市| 西乌珠穆沁旗| 湛江市| 巫山县| 商洛市| 剑阁县| 永善县| 富民县| 夏河县| 夹江县| 灌阳县| 凤山县| 响水县| 巍山| 吴忠市| 新宁县| 和顺县| 丰原市| 肃宁县| 伊金霍洛旗| 新绛县| 从化市| 翁牛特旗| 武宣县| 平潭县|