好记性不如烂笔头。记一下对ApplicationContext实例化的过程的吧。
代码:
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
首先进入的代码是:
static {
ContextClosedEvent.class.getName();
}
这个代码块在AbstractApplicationContext里,是ClassPathXmlApplicationContext的父类,所以静态代码块先运行。(所以这句代码的作用是啥呢?求大佬指导)
进入代码:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
之后调用本类的另一个构造方法
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
调用父类AbstractXmlApplicationContext构造方法
调用父类AbstractRefreshableConfigApplicationContext构造方法
调用父类AbstractRefreshableApplicationContext构造方法
调用父类AbstractApplicationContext构造方法
public AbstractApplicationContext(ApplicationContext parent) {
this();//调用AbstractApplicationContext的无参构造方法
this.setParent(parent);
}
public AbstractApplicationContext() {
this.logger = LogFactory.getLog(this.getClass());
this.id = ObjectUtils.identityToString(this);
//这个应用上下文的ID
this.displayName = ObjectUtils.identityToString(this);
//这个应用上下文(ApplicationContext)的名称,由这个类的 类名+ @ + 这个context对象的hash值 组成。
this.beanFactoryPostProcessors = new ArrayList();
///这个List用于存放Bean工厂处理器(BeanFactoryPostProcessor)
this.active = new AtomicBoolean();
//当前context是否正处于的活动状态
this.closed = new AtomicBoolean();
//当前context是否关闭
this.startupShutdownMonitor = new Object();
this.applicationListeners = new LinkedHashSet();
this.resourcePatternResolver = this.getResourcePatternResolver();
//从 PathMatchingResourcePatternResolver 类上的注释可知 该类支持 Ant 风格的路径解析
}
设置配置文件路径
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) {
//遍历路径数组,将 解析(分解) 后的路径放到 configLocations 中
this.configLocations[i] = this.resolvePath(locations[i]).trim();
}
} else {
this.configLocations = null;
}
}
调用refresh方法
AbstractApplicationContext的refresh()方法是spring的核心,在其中完成了容器的初始化
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
//实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
//这里得新写一篇
//以上就是实例化ApplicationContext的过程