好記性不如爛筆頭。記一下對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的過程