详解Spring ApplicationContext加载过程

作者:柠檬时间 时间:2023-07-17 01:07:43 

1、找准入口,使用ClassPathXmlApplicationContext的构造方法加载配置文件,用于加载classPath下的配置文件


//第一行,执行完成之后就完成了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}使用系统的变量替换
 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的源码,实际上执行的是AbstractPropertyResolver的doResolverPlaceholders方法


/**
* text : 需要解析的路径
* PropertyPlaceholderHelper : 这个是解析系统占位符的辅助类,主要用来将占位符替换成系统的环境变量
*/
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,便于后续到操作
 StringBuilder buf = new StringBuilder(strVal);

//this.placeholderPrefix这个是占位符的前缀 ${,在创建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) {
    //此时继续递归解析出1.8.0_60中的占位符
    propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
    //将路径中的占位符替换成系统变量的值,比如将${java.version} 替换成 1.8.0_60
    buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
    if (logger.isTraceEnabled()) {
     logger.trace("Resolved placeholder '" + placeholder + "'");
    }
    //继续在路径字符串中剩余的子串中查找占位符,如果有占位符,那么还会继续解析占位符
    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();

//需要创建beanFactory,如果已经存在beanFactory,那么关闭,详细其请看 10
  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 准备上下文工厂,详情见12
  prepareBeanFactory(beanFactory);

try {
   //允许子类向后置处理器添加组件
   postProcessBeanFactory(beanFactory);

// 调用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor这两个后置处理器
   invokeBeanFactoryPostProcessors(beanFactory);

// 注册BeanPostProcessor,用来拦截bean的创建,详情见 14
   registerBeanPostProcessors(beanFactory);

//初始化消息源
   initMessageSource();

// 初始化应用程序事件广播器,用户可以自定义一个事件广播器,如果用户没有定义,那么使用默认的事件广播器SimpleApplicationEventMulticaster
   initApplicationEventMulticaster();

// 在其他子类中初始化bean
   onRefresh();

// 检测事件 *
   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 {
  //重新创建一个beanFactory
  DefaultListableBeanFactory beanFactory = createBeanFactory();
  //设置序列化id
  beanFactory.setSerializationId(getId());

//定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及
  //设置@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 {

//创建要给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);

//在添加一个应用程序 *
 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类型的后置处理器

//存放实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor
  List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

//遍历,如果实现了PriorityOrdered这个接口就保存下来
  for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    processedBeans.add(ppName);
   }
  }

//按照优先级排序
  OrderComparator.sort(priorityOrderedPostProcessors);
  //添加进入集合
  registryPostProcessors.addAll(priorityOrderedPostProcessors);

//首先调用实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor
  invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

// ---- 下面是调用实现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);
 }

//--- 下面是调用实现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的创建,这个接口可以实现在Bean初始化和初始化之后执行相关的操作


//依然这里依然调用的PostProcessorRegistrationDelegate,其中包含了注册后置处理器和调用后置处理器的方法,相当于一个代理人
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

//PostProcessorRegistrationDelegate中的注册BeanPostProcessors的方法
//其中beanFactory这个新创建的beanFactory,其中的BeanPostProcessor都没有注册,applicationContext这个是之前创建的,其中的处理器已经注册过了
public static void registerBeanPostProcessors(
  ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

//根据类型新加载全部的BeanFactoryProcessor的类,
 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

//创建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));
}

来源:https://segmentfault.com/a/1190000039680860

标签:Spring,ApplicationContext,加载过程
0
投稿

猜你喜欢

  • Unity3D Ui利用shader添加效果

    2022-09-17 15:32:47
  • 保证缓存和数据库的数据一致性详解

    2023-11-18 08:10:44
  • java实现求两个字符串最长公共子串的方法

    2023-04-03 12:15:05
  • 基于JWT.NET的使用(详解)

    2021-07-09 22:15:25
  • Spring Boot集成Ehcache缓存解决方式

    2023-05-13 08:27:27
  • c#使用xamarin编写拨打电话程序

    2023-09-04 18:09:20
  • Android实现今日头条订阅频道效果

    2021-10-29 23:30:00
  • C#实现PDF文件添加图片背景

    2022-04-03 20:45:35
  • Gradle的基本使用

    2023-05-29 00:08:42
  • Servlet的5种方式实现表单提交(注册小功能),后台获取表单数据实例

    2022-08-19 20:58:06
  • java文件重命名(文件批量重命名)实例程序代码分享

    2023-07-20 06:45:06
  • c#高效率导出多维表头excel的实例代码

    2022-10-17 04:45:49
  • Java日期时间类(Date、DateFormat、Calendar)解析

    2022-08-06 18:02:14
  • Android编程使用WebView实现与Javascript交互的方法【相互调用参数、传值】

    2023-12-04 01:39:07
  • java递归实现汉诺塔步骤介绍

    2022-03-03 09:44:17
  • 从Cocos2d-x2迁移到Cocos2d-x3的过程分享

    2021-06-07 23:52:28
  • Android Rsa数据加解密的介绍与使用示例

    2023-06-24 04:51:38
  • 10个C#程序员经常用到的实用代码片段

    2022-12-01 13:02:58
  • Android使用Item Swipemenulistview实现仿QQ侧滑删除功能

    2021-08-16 19:47:35
  • 解决spring mvc 多数据源切换,不支持事务控制的问题

    2022-09-30 03:39:56
  • asp之家 软件编程 m.aspxhome.com