容器的功能扩展

ApplicationContext扩展了BeanFactory中的所有功能,使用ApplicationContext的方法如下:

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

那么从ClassPathXmlApplicationContext类开始深入学习。

BeanFactory家族图

关于ClassPathXmlApplicationContext这个类,可以查看:spring BeanFactory家族之ClassPathXmlApplicationContext

设置配置路径

这个构造函数是支持传入xml路径数组的,在里面的调用中你会发现路径会被解析,如果路径中存在${var}, 那么会在系统环境变量中找到并替换。

扩展功能

设置了路径后,就可以解析xml文件及实现各种功能了。可以说refresh()函数几乎包含了ApplicationContext中提供的所有功能,而且此函数中逻辑非常清晰。这个函数在AbstractApplicationContext#refresh中。我们来看一下AbstractApplicationContext#refresh这个方法:

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 准备刷新的上下文环境
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 初始化Bean环境并进行xml文件读取
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 对BeanFactory进行各种g功能填充
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 子类覆盖方法做额外的处理
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 激活各种BeanFactory处理器
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean的时候。
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 为上下文初始化Message源,即不同语言的消息体,国际化处理。
            initMessageSource();

            // Initialize event multicaster for this context.
            // 初始化消息广播器,并放入applicationEventMulticaster这个bean中。
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 留给子类来初始化其他的bean
            onRefresh();

            // Check for listener beans and register them.
            // 在所有的注册的bean中查找Listener Bean,注册到消息广播器中。
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            // 初始化剩下的单实例(非惰性的)
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人。
            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();
        }
    }
}

总结一下ClassPathXmlApplicationContext的初始化步骤,并从中解释一下它为我们提供的功能:

  • 初始化前的准备工作,例如对系统属性或者环境变量进行准备和验证。
  • 初始化BeanFactory,并进行XML文件读取。
  • 对BeanFactory进行各种功能填充。(@Qualifier和@Autowired注解正是在这一步骤中添加的支持)
  • 子类覆盖方法做额外的处理。
  • 激活各种BeanFactory处理器
  • 注册拦截bean创建的bean处理器,这里只是注册,真正调用的是在getBean的时候。
  • 为上下文初始化Message源,即对不同语言的消息体进行国际化处理。
  • 初始化应用消息广播器,并放入“ApplicationEventMulticaster”bean中。
  • 留给子类来初始化其他的bean
  • 在所有注册的bean中查找Listener bean,注册到消息广播器中。
  • 初始化剩下的单实例(非惰性的)
  • 完成刷新过程,通知生命周期处理器LifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人。

results matching ""

    No results matching ""