详解Spring ApplicationContext加载过程

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));
 }

以上就是详解Spring ApplicationContext加载过程的详细内容,更多关于Spring ApplicationContext加载过程的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring主配置文件(applicationContext.xml) 导入约束详解

    eclipse导入Spring配置文件约束  Windows-Preference-XML-XMLCatalog 点 Add 选File System 下spring的解压包下的schema文件夹,选beans,然后选择spring对应的版本的xsd文件 选择指定xsd文件,再Key的路径后面添加"/spring-beans-4.2.xsd"点ok 创建applicationContext.xml   写根元素 <beans></beans> Add导入XSI,

  • Spring获取ApplicationContext对象工具类的实现方法

     Spring获取ApplicationContext对象工具类的实现方法 (1)实现的工具类: package com.util; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; final public class ApplicationContextUtil { private s

  • spring中通过ApplicationContext getBean获取注入对象的方法实例

    用SpringContextUtil实现ApplicationContextAware package util; import java.util.Locale; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; pub

  • JSP Spring ApplicationContext的国际化支持

    JSP Spring  ApplicationContext的国际化支持 1.ApplicationContext接口继承了MessageResource接口,因此使用ApplicationContext作为spring容器可以使用国际化资源文件. 2.在MessageResource接口中定义了两个主要用于国际化的方法: String getMessage(String param,Object[] args,Locale loc) ; String getMessage(String par

  • Spring通过ApplicationContext主动获取bean的方法讲解

    问题1: 有个异步线程Runnable里面需要用到dao,无法通过AutoWired和compoment注解传递进来. 于是希望通过Spring context主动去获取bean. 问题2: getBean(name)获取失败. 解决: 默认的dao的name=类名(首字母小写) 例如: 接口名称:TemplateDao 则getName("templateDao")即可 通用的SpringContextUtil获取Bean 1.实现ApplicationContextAware接口

  • Spring中BeanFactory和ApplicationContext的作用和区别(推荐)

    作用: 1.BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期.2.ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能: a. 国际化支持 b. 资源访问:Resource rs = ctx. getResource("classpath:config.properties"), "file:c:/config.properties&qu

  • 详解spring applicationContext.xml 配置文件

    applicationContext.xml 文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http

  • Spring MVC之WebApplicationContext_动力节点Java学院整理

    如果你使用了listener监听器来加载配置,一般在Struts+Spring+Hibernate的项目中都是使用listener监听器的.如下 Java代码 <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> Spring会创建一个WebApplicationContext上下文,称为父上下

  • SpringBoot获取ApplicationContext的3种方式

    ApplicationContext是什么? 简单来说就是Spring中的容器,可以用来获取容器中的各种bean组件,注册监听事件,加载资源文件等功能. Application Context获取的几种方式 1 直接使用Autowired注入 @Component public class Book1 { @Autowired private ApplicationContext applicationContext; public void show (){ System.out.printl

  • Spring IoC学习之ApplicationContext中refresh过程详解

    refresh() 该方法是 Spring Bean 加载的核心,它是 ClassPathXmlApplicationContext 的父类 AbstractApplicationContext 的一个方法 , 顾名思义,用于刷新整个Spring 上下文信息,定义了整个 Spring 上下文加载的流程. public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShu

  • 详解Spring Boot的GenericApplicationContext使用教程

    教程展示了如何在Spring应用程序中使用GenericApplicationContext .在该示例中,我们创建了一个Spring Boot控制台应用程序. Spring是一个流行的Java应用程序框架,Spring Boot 是Spring的演变,可以帮助您轻松创建独立的,基于生产级别的Spring应用程序. GenericApplicationContext是一个实现ApplicationContext,它不预设指定任何bean定义格式; 例如XML或注释. 在下面的应用程序中,我们Ge

随机推荐