2019独角兽企业重金招聘Python工程师标准>>>
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()方法内部
@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.
// 告诉子类刷新内部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的初始化部分。整个启动的流程可以简单的总结一下为以下流程。