91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

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

彭阳县| 平山县| 秭归县| 宁河县| 陵水| 玉门市| 桂东县| 尤溪县| 壶关县| 三原县| 邵阳市| 元氏县| 肇州县| 柳州市| 栖霞市| 旬邑县| 新干县| 兴安县| 肇庆市| 南部县| 桐梓县| 渭南市| 新兴县| 荥经县| 丰都县| 饶平县| 贺州市| 无棣县| 九江市| 佛教| 弥渡县| 聂拉木县| 左贡县| 铜梁县| 白城市| 庆安县| 新源县| 灌阳县| 无极县| 丹江口市| 枣强县|