ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
首先可以看到ClassPathXmlApplicationContext继承于BeanFactory和ResourceLoader两个父类接口。
我们再来看ClassPathXmlApplicationContext的构造方法做了什么
//调用了自己的另一个构造方法public ClassPathXmlApplicationContext(String... configLocations) throws BeansException { this(configLocations, true, null);}
/**调用了父类的构造方法,同时设置了配置文件的地址,并判断是否刷新**/public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); }}
跟进源码里面,super(parent),一直调用到了AbstractApplicationContext类
/** * Create a new AbstractApplicationContext with the given parent context. * 第一次传递的parent为null * @param parent the parent context */public AbstractApplicationContext(ApplicationContext parent) { this(); setParent(parent);}
其中this()方法
/** * Create a new AbstractApplicationContext with no parent. * 获取了一个资源解析器 */public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver();}
所以在初始化的第一步就是设置了一个资源的解析器,让我们再回到第一步的初始化方法
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {/** * Create a new AbstractApplicationContext with no parent. * 获取了一个资源解析器 */ super(parent);/** * Create a new AbstractApplicationContext with no parent. * 设置配置文件的地址 */ setConfigLocations(configLocations);/** * Create a new AbstractApplicationContext with no parent. * 重点在这个refresh方法 */ if (refresh) { refresh(); }}
refresh()方法是实现了ConfigurableApplicationContext接口的refresh方法,
进入refresh()方法内部
@Overridepublic void refresh() throws BeansException, IllegalStateException { // 首先加锁,保证同一时间只会执行一个 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 告诉子类刷新内部bean工厂,如果beanfactory已存在会先销毁所有的bean,然后关闭beanfactory。然后创建beanfactory,加载beanDefinitions(bean定义) ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 准备beanfactory供context使用 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 允许子类在context中的子类执行后置操作 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. /// 初始化其他特殊的bean onRefresh(); // Check for listener beans and register them. // 注册监听者 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 初始化所有非lazy的单例bean 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(); } }}
refresh()方法没有具体的展开,下次继续学习bean的初始化部分。整个启动的流程可以简单的总结一下为以下流程。