Spring ApplicationContext下的refresh()方法

Posted kl0428

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring ApplicationContext下的refresh()方法相关的知识,希望对你有一定的参考价值。

public class BeanTest{
    @Test
    public void test(){
        ApplicationContext applicationContext  = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(applicationContext);
        Student student = (Student)applicationContext.getBean("student");
        student.play();
        System.out.println(student);
        //关闭容器
        ((AbstractApplicationContext)applicationContext).close();
    }
}

调用ApplicationContext,执行refresh() 

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset ‘active‘ flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring‘s core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

  1、刷新容器前的预处理prepareRefresh

  
// Initialize any placeholder property sources in the context environment.
  //初始化一些属性设置
  initPropertySources();

  // Validate that all properties marked as required are resolvable:
  // see ConfigurablePropertyResolver#setRequiredProperties
  //校验属性的合法性
  getEnvironment().validateRequiredProperties();
  // Allow for the collection of early ApplicationEvents,
  // to be published once the multicaster is available...
  //保存容器中的早期事件的容器 Set 集合
  this.earlyApplicationEvents = new LinkedHashSet<>();

  

  2、获取 beanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

  //构造一个 beanFactory  

  this.beanFactory = new DefaultListableBeanFactory();

  //获取 BeanFactory 返回的上一步构 GenericApplicationContext 类构造器创建的 beanFactory

  ConfigurableListableBeanFactory beanFactory = getBeanFactory();

  //返回 beanFactory 【ConfigurableListableBeanFactory 的实例实例对象】

  return beanFactory;

  3、beanFactory 的预准备工作  prepareBeanFactory(beanFactory);

  

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }

  4、beanFactory 准备完成的后置处理工作 postProcessBeanFactory(beanFactory);

  5、执行 beanFactoryPostProcessors 方法  invokeBeanFactoryPostProcessors(beanFactory);

    执行 invokeBeanFactoryPostProcessors 的方法 

    BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor

      先执行 BeanDefinitionRegistryPostProcessor 的方法
      再执行 BeanFactoryPostProcessors 的方法
  6、注册 BeanPostProcessors 【 Bean 的后置处理器 】registerBeanPostProcessors(beanFactory);
    优先级接口PriorityOrdered 和 Ordered
  7、初始化 MessageSource 组件  initMessageSource();
  8、初始化事件派发器 initApplicationEventMulticaster();
  9、留给子容器(子类)onRefresh();
  10、给容器中将所有项目里面的ApplicationListener注册进来  registerListeners();
  11、初始化所有剩下的单实例 Bean(没有配置赖加载的 lazy!=true)  finishBeanFactoryInitialization(beanFactory);
    1>、初始化所有剩下的单实例bean
      beanFactory.preInstantiateSingletons();
    2>、将容器中所有的 bean 加入到 List中
      List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    3>、遍历该 List
      for (String beanName : beanNames) {
         ...
      }
    4>、获取 bean 定义信息
       RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    5>、bean 不是抽象的、是单例的、非懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
          ...
      }
    6>、是否为 FactoryBean ,是则调用 FactoryBean 的创建方法,否则执行 getBean() 方法
       if (isFactoryBean(beanName)) {
            ...     
      }
    7>、调用 getBean() 方法 -> 内部再调用 doGetBean() 方法
      (1)、尝试从从缓存中获取 bean
       Object sharedInstance = getSingleton(beanName);
 
        (2)、获取 bean 定义信息
       RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 
      (3)、判断是否有其他依赖,如果有其他依赖,注册依赖的 bean 并调用 getBean() 方法创建
        String[] dependsOn = mbd.getDependsOn();
          if (dependsOn != null) {
               for (String dep : dependsOn) {
                   if (isDependent(beanName, dep)) {
                       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                             "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘");
                   }
                 registerDependentBean(dep, beanName);
                 getBean(dep);
               }
           }

      (4)、
进入单实例 bean 的创建流程  return createBean(beanName, mbd, args);

以上是关于Spring ApplicationContext下的refresh()方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring -- Spring相关API (ApplicationContext getBean)

spring BeanFactory 与ApplicationContext

BeanFactory and ApplicationContext in Spring

Spring获取ApplicationContext

Spring 学习笔记——IoC容器(ApplicationContext)

Spring ApplicationContext下的refresh()方法