高级容器ApplicationContext的初始过程---总览与概述

来源:互联网 发布:淘宝日本直邮物流信息 编辑:程序博客网 时间:2024/05/21 01:30

     作为Spring的IoC最为核心的部分便是“容器”的概念,它用来统一管理所有bean的定义以及bean之间可能的相互依赖关系。在Spring中,容器分为基础容器(BeanFactory)和高级容器(ApplicationContext),BeanFactory作为Spring最底层的核心实现,就像是Spring的根基,提供了Spring最基本的功能:bean的管理。而ApplicationContext则是对BeanFactory的扩展(继承自BeanFactory),提供了更为丰富的功能,如国际化资源访问,事件传播机制等,对于日常工作中开发的Spring企业应用和系统,都基本以ApplicationContext为基础,所以掌握ApplicationContext的原理和实现就显得尤为重要。下面就对ApplicationContext的底层实现做一个深入的了解。

    ApplicationContext作为高级容器接口,有很多常用的实现类,如FileSystemXmlApplicationContext和ClassPathXmlApplicationContext,它们都继承于AbstractXmlApplicationContext抽象类(ApplicationContext接口实现基础核心类)。首先我们以FileSystemXmlApplicationContext加载配置文件为例,看看该类是怎么一步一步完成初始化的:

 ApplicationContext ac=new FileSystemXmlApplicationContext("myApplicationContextTest.xml");
进入FileSystemXmlApplicationContext类,看一下构造过程:
public FileSystemXmlApplicationContext(String configLocation) throws BeansException {        this(new String[] {configLocation}, true, null);    }    public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)            throws BeansException {        super(parent);        setConfigLocations(configLocations);//设置配置路径        if (refresh) {            refresh();//容器的初始化入口        }    }

跟踪setConfigLocations(configLocations)方法,进入到AbstractRefreshableConfigApplicationContext类中,实现方法如下:

public void setConfigLocations(String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");this.configLocations = new String[locations.length];for (int i = 0; i < locations.length; i++) {  this.configLocations[i] = resolvePath(locations[i]).trim();//解析给定的路径}}else {this.configLocations = null;} }

下面我们重点看一下refresh()方法的实现,该方法封装在了基础核心抽象类AbstractApplicationContext中:

@Overridepublic void refresh() throws BeansException, IllegalStateException {    synchronized (this.startupShutdownMonitor) { //锁机制,同一时间只能被单一访问//准备上下文环境的初始化,对系统属性和环境变量进行准备和验证prepareRefresh();// 初始化beanfactory,并进行XML文件读取ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//丰富beanfactory的功能,如增加类加载机制,SPEL表达式语言支持,后置处理器等等prepareBeanFactory(beanFactory);try {//子类覆盖方法,再进一步做一些其他工作,如注册系统上下文request/session属性以及和servlet相关的处理postProcessBeanFactory(beanFactory);// 激活各种beanfactory处理器invokeBeanFactoryPostProcessors(beanFactory);// 注册拦截bean所创建bean处理器registerBeanPostProcessors(beanFactory);// 初始化message消息源,支持多语言,实现国际化initMessageSource();// 初始化应用消息传播器initApplicationEventMulticaster();// 留给子类实现,完成其他的bean的初始化onRefresh();//检查bean监听器,并注册到消息广播器中registerListeners();// 初始化所有剩下的非惰性的单实例beanfinishBeanFactoryInitialization(beanFactory);// 最后一步,完成刷新过程,通知生命周期处理器完成初始化finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// 销毁已经创建单实例beandestroyBeans();//重置active标志cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {//重置公共缓存机制resetCommonCaches();}}   }

从这里可以看出,高级容器ApplicationContext的初始化过程代码结构非常清晰明了,并没有我们想象中的那么难,“大而化小,逐渐细分,统筹工作”正是体现Spring乃至其他很多优秀开源软件的核心思想。下面沿着上述的初始化总体流程,继续深入下去,发现每一步所做的具体工作也并没有那么简单。






0 0
原创粉丝点击