最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Spring ApplicationContext加載過程

 更新時間:2021年03月22日 10:56:20   作者:檸檬時間  
這篇文章主要介紹了Spring ApplicationContext加載過程的相關資料,幫助大家更好的理解和學習使用spring框架,感興趣的朋友可以了解下

1、找準入口,使用ClassPathXmlApplicationContext的構造方法加載配置文件,用于加載classPath下的配置文件

//第一行,執(zhí)行完成之后就完成了spring配置文件的加載,刷新spring上下文
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(
    "classpath:spring-mvc.xml");
//獲取實例Bean
Person person=context.getBean("person",Person.class);

2、ClassPathXmlApplicationContext構造方法源碼如下:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
   throws BeansException {
  //設置父級的ApplicationContext,null
  super(parent);
  //1.設置配置文件的路徑, 2. 將路徑中的占位符${placeholder}使用系統(tǒng)的變量替換
  setConfigLocations(configLocations);
  if (refresh) {
   refresh();
  }
 }

3、主要方法為setConfigLocation(configLocation),這個方法調用其父類AbstractRefreshableConfigApplicationContext中的方法

//locations : 配置文件路徑
public void setConfigLocations(String[] locations) {
  if (locations != null) {
   //斷言
   Assert.noNullElements(locations, "Config locations must not be null");
   //存儲配置文件路徑的數組,存儲去掉占位符后的文件路徑數組
   this.configLocations = new String[locations.length];
   //遍歷locations,解析占位符
   for (int i = 0; i < locations.length; i++) {
     //調用resolvePath解析占位符
    this.configLocations[i] = resolvePath(locations[i]).trim();
   }
  }
  else {
   this.configLocations = null;
  }
 }

4、進入resovePath的源碼,實際上執(zhí)行的是AbstractPropertyResolver的doResolverPlaceholders方法

/**
* text : 需要解析的路徑
* PropertyPlaceholderHelper : 這個是解析系統(tǒng)占位符的輔助類,主要用來將占位符替換成系統(tǒng)的環(huán)境變量
*/
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
  //調用PropertyPlaceholderHelper類中的replacePlaceholders方法
  return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
   public String resolvePlaceholder(String placeholderName) {
    return getPropertyAsRawString(placeholderName);
   }
  });
 }

5、進入PropertyHelper的replacePlaceholder方法,實際上調用PropertyPlaceholderHelper的parseStringValue解析占位符

public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
  Assert.notNull(value, "Argument 'value' must not be null.");
  //調用的是parseStringValue方法
  return parseStringValue(value, placeholderResolver, new HashSet<String>());
 }
 
/**
* strVal : 需要解析的字符串,就是配置文件的路徑
* placeholderResolver : 策略接口,占位符解析器
* visitedPlaceholders : 存儲已經訪問過的占位符
**/
protected String parseStringValue(
   String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
  //將strval轉換成StringBuilder,便于后續(xù)到操作
  StringBuilder buf = new StringBuilder(strVal);
 
 //this.placeholderPrefix這個是占位符的前綴 ${,在創(chuàng)建PropertyHelper的時候就已經指定了占位符的placeholderPrefix="${" ,placeholderSuffix="}",valueSeparator=":"
 //獲取前綴在這個配置文件路徑中的開始索引 
  int startIndex = strVal.indexOf(this.placeholderPrefix);
 
  while (startIndex != -1) {
   //占位符前綴在路徑中的結束索引
   int endIndex = findPlaceholderEndIndex(buf, startIndex);
   
   //如果結束索引存在
   if (endIndex != -1) {
    
    //此時取出${plcaeholder}中的占位符內容placeholder
    String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
    
    //保存取出來的占位符內容placeholder
    String originalPlaceholder = placeholder;
    
    //如果占位符中的內容已經被訪問過了,拋出出異常返回,遞歸結束的條件
    if (!visitedPlaceholders.add(originalPlaceholder)) {
     throw new IllegalArgumentException(
       "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
    }
    
    //遞歸解析已經取出的占位符中的內容 palceholder
    placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
    
    
    //這個最重要的一步,將解析占位符內容placeholder的值,比如將java.version轉換成1.8.0_60
    String propVal = placeholderResolver.resolvePlaceholder(placeholder);
    
    if (propVal == null && this.valueSeparator != null) {
     int separatorIndex = placeholder.indexOf(this.valueSeparator);
     if (separatorIndex != -1) {
      String actualPlaceholder = placeholder.substring(0, separatorIndex);
      String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
      propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
      if (propVal == null) {
       propVal = defaultValue;
      }
     }
    }
    //如果解析出來的占位符不為空,比如${java.version}將被解析成 1.8.0_60
    if (propVal != null) {
     //此時繼續(xù)遞歸解析出1.8.0_60中的占位符
     propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
     //將路徑中的占位符替換成系統(tǒng)變量的值,比如將${java.version} 替換成 1.8.0_60
     buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
     if (logger.isTraceEnabled()) {
      logger.trace("Resolved placeholder '" + placeholder + "'");
     }
     //繼續(xù)在路徑字符串中剩余的子串中查找占位符,如果有占位符,那么還會繼續(xù)解析占位符
     startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
    }
    else if (this.ignoreUnresolvablePlaceholders) {
     // Proceed with unprocessed value.
     startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
    }
    else {
     throw new IllegalArgumentException("Could not resolve placeholder '" +
       placeholder + "'" + " in string value \"" + strVal + "\"");
    }
    //將已轉換成功的占位符從以訪問的集合中移除即可
    visitedPlaceholders.remove(originalPlaceholder);
   }
   else {
    startIndex = -1;
   }
  }
 
  return buf.toString(); //將解析完成之后的配置文件返回
 }

6、然后是ClassPathXmlApplicationContext中的refresh方法,實際上調用的是父類AbstractApplicationContext的方法

//刷新spring上下文
public void refresh() throws BeansException, IllegalStateException {
  synchronized (this.startupShutdownMonitor) {
   //在刷新之前設置一些參數,比如設置開始時間戳,上下文是否激活的標志,輸出刷新上下文的信息,驗證一些必要的屬性
   prepareRefresh();
 
   //需要創(chuàng)建beanFactory,如果已經存在beanFactory,那么關閉,詳細其請看 10
   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
   // 準備上下文工廠,詳情見12
   prepareBeanFactory(beanFactory);
 
   try {
    //允許子類向后置處理器添加組件
    postProcessBeanFactory(beanFactory);
 
    // 調用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor這兩個后置處理器
    invokeBeanFactoryPostProcessors(beanFactory);
 
    // 注冊BeanPostProcessor,用來攔截bean的創(chuàng)建,詳情見 14
    registerBeanPostProcessors(beanFactory);
 
    //初始化消息源
    initMessageSource();
 
    // 初始化應用程序事件廣播器,用戶可以自定義一個事件廣播器,如果用戶沒有定義,那么使用默認的事件廣播器SimpleApplicationEventMulticaster
    initApplicationEventMulticaster();
 
    // 在其他子類中初始化bean
    onRefresh();
 
    // 檢測事件監(jiān)聽器
    registerListeners();
 
    //完成實例化剩余的單例(non-lazy-init)
    finishBeanFactoryInitialization(beanFactory);
 
    // 完成刷新,初始化生命周期處理器......
    finishRefresh();
   }
 
   catch (BeansException ex) {
    // Destroy already created singletons to avoid dangling resources.
    destroyBeans();
 
    // Reset 'active' flag.
    cancelRefresh(ex);
 
    // Propagate exception to caller.
    throw ex;
   }
  }
 }

7、進入obtainFreshBeanFactory方法

//AbastractApplicationContext的方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
  //實際刷新上下文的方法,這個方法就是實際的刷新上下文方法,其中會調用loadBeanDefinitions(beanFactory);加載配置文件中的內容到BeanDefiniton中
  refreshBeanFactory();
  ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  if (logger.isDebugEnabled()) {
   logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
  }
  return beanFactory;
 }
 
 
 //org.springframework.context.support.AbstractRefreshableApplicationContext中的方法
 //AbstractApplicationContext的子類中的方法
 @Override
 protected final void refreshBeanFactory() throws BeansException {
  //如果其中有beanfactory,那么銷毀
  if (hasBeanFactory()) {
   destroyBeans();
   closeBeanFactory();
  }
  
  try {
   //重新創(chuàng)建一個beanFactory
   DefaultListableBeanFactory beanFactory = createBeanFactory();
   //設置序列化id
   beanFactory.setSerializationId(getId());
   
   //定制beanFactory,設置相關屬性,包括是否允許覆蓋名稱的不同定義的對象及循環(huán)依賴以及
   //設置@Autowired和@Qualifier,注解解析器QualifierAnnotationAutowireCandidateResolver
   customizeBeanFactory(beanFactory);
   //加載BeanDefine 詳情見 11
   loadBeanDefinitions(beanFactory);
   synchronized (this.beanFactoryMonitor) {
    this.beanFactory = beanFactory;
   }
  }
  catch (IOException ex) {
   throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
  }
 }

8、進入loadBeanDefinitions(beanFactory)方法

 //這個是org.springframework.context.support.AbstractXmlApplicationContext類中的方法
 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
  
  //創(chuàng)建要給beanDefinitionReader,用于讀取BeanDefinition
  XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
 
  //配置XmlBeanDefinitionReader
  beanDefinitionReader.setEnvironment(this.getEnvironment());
  beanDefinitionReader.setResourceLoader(this); 
  beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
 
  initBeanDefinitionReader(beanDefinitionReader);
  //加載BeanDefiniton,主要的功能從配置文件中讀取BeanDefiniton注冊到注冊表中
  loadBeanDefinitions(beanDefinitionReader);
 }

9、prepareBeanFactory:準備BeanFactory

//準備BeanFactory,設置一些參數,比如后置處理器,
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  //設置類加載器
  beanFactory.setBeanClassLoader(getClassLoader());
  
 //設置表達式解析器,用來解析BeanDefiniton中的帶有表達式的值
  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  
 
  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 
  // 配置后置處理器,主要的作用就是在spring實例化bean的前后做一些操作
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
  
  //忽略自動裝配的類,這些類都不能使用@Resource或者@Autowired自動裝配獲取對象
  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
  beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
 
  //注冊可解析的自動裝配類
  beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
  beanFactory.registerResolvableDependency(ResourceLoader.class, this);
  beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
  beanFactory.registerResolvableDependency(ApplicationContext.class, this);
 
  //在添加一個應用程序監(jiān)聽器
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
 
  //檢查這些類是否被
  if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
 
   beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
  }
 
  // 將下面這些類注冊到容器中,使用registerSingleton方法注冊,我們可以直接從容器中獲取這些類的對象使用
  if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
   beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
  }
  if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
   beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
  }
  if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
   beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
  }
 }

10、調用BeanFactory的后置處理器,主要的功能就是調用注冊在容器中的BeanFactoryPostProcessor和BeanDefinitionRegistoryPostProcessor

//實例化和調用BeanFactory后置處理器,必須在單例實例化之前調用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  //調用后置處理器注冊委托類的方法調用,getBeanFactoryPostProcessors用于獲取注冊的全部的BeanFactoryPostProcessor
  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
 }
 
//實際的調用方法,PostProcessorRegistrationDelegate中的方法
public static void invokeBeanFactoryPostProcessors(
   ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
 
  // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  Set<String> processedBeans = new HashSet<String>();
  
  //如果beanFactory是BeanDefinitionRegistry的子類,BeanDefinitionRegistry使用來向注冊表中注冊Bean的元信息的(BeanDefintion)
  if (beanFactory instanceof BeanDefinitionRegistry) {
   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
   
   //存放BeanFactoryPostProcessor
   List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
   
   //存放BeanDefinitionRegistryPostProcessor
   List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
     new LinkedList<BeanDefinitionRegistryPostProcessor>();
   
   //遍歷。判斷是否是BeanDefinitionRegistryPostProcessor實例
   for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
     BeanDefinitionRegistryPostProcessor registryPostProcessor =
       (BeanDefinitionRegistryPostProcessor) postProcessor;
     
      //調用BeanDefinitionRegistryPostProcessor
     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
     //添加
     registryPostProcessors.add(registryPostProcessor);
    }
    else {
     //表示這個是BeanFactoryPostProcessor實例,添加進集合
     regularPostProcessors.add(postProcessor);
    }
   }
 
   //--- 根據類型類型獲取beanFactory中注冊的BeanDefinitionRegistryPostProcessor的bean的所有名稱數組
   String[] postProcessorNames =
     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 
   // ---- 首先調用的是BeanDefinitionRegistryPostProcessor類型的后置處理器
   
   //存放實現(xiàn)PriorityOrdered這個接口的BeanDefinitionRegistryPostProcessor
   List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
   
   //遍歷,如果實現(xiàn)了PriorityOrdered這個接口就保存下來
   for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     processedBeans.add(ppName);
    }
   }
   
   //按照優(yōu)先級排序
   OrderComparator.sort(priorityOrderedPostProcessors);
   //添加進入集合
   registryPostProcessors.addAll(priorityOrderedPostProcessors);
   
   //首先調用實現(xiàn)PriorityOrdered這個接口的BeanDefinitionRegistryPostProcessor
   invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
 
   // ---- 下面是調用實現(xiàn)Orderd這個接口的BeanDefinitionRegistryPostProcessor
   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
   List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
   for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     processedBeans.add(ppName);
    }
   }
   OrderComparator.sort(orderedPostProcessors);
   registryPostProcessors.addAll(orderedPostProcessors);
   invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
 
   
   // ---- 最終調用剩余全部的BeanDefinitionRegistryPostProcessor
   
   boolean reiterate = true;
   while (reiterate) {
    reiterate = false;
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
     if (!processedBeans.contains(ppName)) {
      BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
      registryPostProcessors.add(pp);
      processedBeans.add(ppName);
      pp.postProcessBeanDefinitionRegistry(registry);
      reiterate = true;
     }
    }
   }
 
   // 調用BeanFactoryPostProcessor接口中的方法,因為BeanDefitionRegistory繼承了這個接口
   invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  }
 
  else {
   // Invoke factory processors registered with the context instance.
   invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
  }
 
  //--- 下面是調用實現(xiàn)BeanFactoryPostProcessor接口的類,和上面的流程一樣
  String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
 
  // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
  // Ordered, and the rest.
  List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  List<String> orderedPostProcessorNames = new ArrayList<String>();
  List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  for (String ppName : postProcessorNames) {
   if (processedBeans.contains(ppName)) {
    // skip - already processed in first phase above
   }
   else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    orderedPostProcessorNames.add(ppName);
   }
   else {
    nonOrderedPostProcessorNames.add(ppName);
   }
  }
 
  // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
  OrderComparator.sort(priorityOrderedPostProcessors);
  invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
 
  // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
  List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  for (String postProcessorName : orderedPostProcessorNames) {
   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  }
  OrderComparator.sort(orderedPostProcessors);
  invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
 
  // Finally, invoke all other BeanFactoryPostProcessors.
  List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
  for (String postProcessorName : nonOrderedPostProcessorNames) {
   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
  }
  invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
 }

11、注冊BeanPostProcessor,用來攔截Bean的創(chuàng)建,這個接口可以實現(xiàn)在Bean初始化和初始化之后執(zhí)行相關的操作

//依然這里依然調用的PostProcessorRegistrationDelegate,其中包含了注冊后置處理器和調用后置處理器的方法,相當于一個代理人
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
 }
 
//PostProcessorRegistrationDelegate中的注冊BeanPostProcessors的方法
//其中beanFactory這個新創(chuàng)建的beanFactory,其中的BeanPostProcessor都沒有注冊,applicationContext這個是之前創(chuàng)建的,其中的處理器已經注冊過了
public static void registerBeanPostProcessors(
   ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
  
  //根據類型新加載全部的BeanFactoryProcessor的類,
  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
 
  //創(chuàng)建BeanPostProcessor檢測器
  int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
  beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
 
  // Separate between BeanPostProcessors that implement PriorityOrdered,
  // Ordered, and the rest.
  List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
  List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
  List<String> orderedPostProcessorNames = new ArrayList<String>();
  List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
  for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
    priorityOrderedPostProcessors.add(pp);
    if (pp instanceof MergedBeanDefinitionPostProcessor) {
     internalPostProcessors.add(pp);
    }
   }
   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    orderedPostProcessorNames.add(ppName);
   }
   else {
    nonOrderedPostProcessorNames.add(ppName);
   }
  }
 
  // First, register the BeanPostProcessors that implement PriorityOrdered.
  OrderComparator.sort(priorityOrderedPostProcessors);
  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
 
  // Next, register the BeanPostProcessors that implement Ordered.
  List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
  for (String ppName : orderedPostProcessorNames) {
   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   orderedPostProcessors.add(pp);
   if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
   }
  }
  OrderComparator.sort(orderedPostProcessors);
  registerBeanPostProcessors(beanFactory, orderedPostProcessors);
 
  // Now, register all regular BeanPostProcessors.
  List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
  for (String ppName : nonOrderedPostProcessorNames) {
   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   nonOrderedPostProcessors.add(pp);
   if (pp instanceof MergedBeanDefinitionPostProcessor) {
    internalPostProcessors.add(pp);
   }
  }
  registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
 
  // Finally, re-register all internal BeanPostProcessors.
  OrderComparator.sort(internalPostProcessors);
  registerBeanPostProcessors(beanFactory, internalPostProcessors);
 
  beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
 }

以上就是詳解Spring ApplicationContext加載過程的詳細內容,更多關于Spring ApplicationContext加載過程的資料請關注腳本之家其它相關文章!

相關文章

  • 詳談異步log4j2中的location信息打印問題

    詳談異步log4j2中的location信息打印問題

    這篇文章主要介紹了詳談異步log4j2中的location信息打印問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java獲取文件的inode標識符的方法

    java獲取文件的inode標識符的方法

    這篇文章主要介紹了java獲取文件的inode標識符,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • SpringBoot通過請求對象獲取輸入流無數據

    SpringBoot通過請求對象獲取輸入流無數據

    這篇文章主要介紹了使用SpringBoot通過請求對象獲取輸入流無數據,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java數組操作的10大方法

    Java數組操作的10大方法

    下面是精心整理的Java數組操作的10大方法,大部分代碼都來自Stack Overflow,需要的朋友可以參考下
    2014-09-09
  • 最常用的1000個Java類(附代碼示例)

    最常用的1000個Java類(附代碼示例)

    這篇文章主要介紹了最常用的1000個Java類(附代碼示例),需要的朋友可以參考下
    2015-04-04
  • request如何獲取完整url(包括域名、端口、參數)

    request如何獲取完整url(包括域名、端口、參數)

    這篇文章主要介紹了request如何獲取完整url(包括域名、端口、參數)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 一篇文章帶你了解MySQL數據庫基礎

    一篇文章帶你了解MySQL數據庫基礎

    這篇文章主要介紹了MySql數據庫基礎知識點,總結整理了mysql數據庫基本創(chuàng)建、查看、選擇、刪除以及數據類型相關操作技巧,需要的朋友可以參考下
    2021-08-08
  • SpringBoot + Mybatis增刪改查實戰(zhàn)記錄

    SpringBoot + Mybatis增刪改查實戰(zhàn)記錄

    這篇文章主要給大家介紹了關于SpringBoot + Mybatis增刪改查的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05
  • Java?List排序4種寫法整理

    Java?List排序4種寫法整理

    這篇文章主要給大家介紹了關于Java?List排序4種寫法整理的相關資料,在有的時候我們會需要對List進行排序,在Java中如何實現(xiàn)呢,本文記錄一下Java中對List的幾種排序方式,需要的朋友可以參考下
    2023-08-08
  • java圖形界面AWT編寫計算器

    java圖形界面AWT編寫計算器

    這篇文章主要為大家詳細介紹了基于java語言下圖形界面AWT編寫計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評論

体育| 荔浦县| 东乡县| 唐河县| 尼勒克县| 习水县| 舒兰市| 凌源市| 星子县| 万载县| 荆门市| 资源县| 景德镇市| 梁河县| 武强县| 始兴县| 陈巴尔虎旗| 错那县| 仙居县| 蓬安县| 民乐县| 烟台市| 咸宁市| 旬邑县| 岗巴县| 沐川县| 屏山县| 昭觉县| 潞西市| 凤凰县| 水城县| 嘉禾县| 邳州市| 松江区| 巩留县| 南开区| 旬阳县| 南华县| 兴山县| 鹿泉市| 广南县|