同前一篇一样,本文的分析还是基于Spring的web应用。
从web.xml里面配置的ContextLoaderListener开始。
ContextLoaderListener引用了一个ContextLoader(可以是它自身);
ContextLoader引用了一个WebApplicationContext;
WebApplicationContext本身是一个beanFactory. 如果不指定,默认的实现类是
XmlWebApplicationContext--这个类的实例是一个beanFactory,同时也引用了一个BeanFactory. (Decorator Pattern);
其中bean的加载是由AbstractApplicationContext的refresh方法调用的。
为了稍微形象的描述,我把refresh方法的调用层次贴了出来。
在ContextLoader的createWebApplicationContext里面,新建了一个ApplicationContext,并且刷新这个context.
新建的代码:
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
刷新的代码:
wac.refresh();
refresh方法的实现是在XmlWebApplicationContext的父类AbstractApplicationContext里面实现的。
refresh里面完成了WebApplicationContext里面的beanfactory的初始化和bean载入,beanfactorypostprocessor的调用,beanpostprocessor的注册,ApplicationEvent的监听和注册,non-lazy-init的bean的初始化。
换言之,已经把该准备的都准备好了,只需要有请求来获取bean,就根据情况或返回已经初始化的bean或进行bean的Instantiation 和 Initialization。
源码如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
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.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
注意其中的obtainFreshBeanFactory方法,beanFactory的初始化是由这个方法调用的。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
继续追踪refreshBeanFactory方法,发现是在AbstractRefreshableApplicationContext中实现的。
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
由此可见,正是在refreshBeanFactory中,新建了一个DefaultListableBeanFactory并且载入了所有BeanDefinition.(载入过程在后续的篇章中继续分析)。
OK.现在脉络清楚了。我们知道了contextLoader在哪里获取了WebApplicationContext,知道了WebApplicationContext在哪里获取了beanFactory,知道了beanFactory在哪里创建和载入bean.
后面需要关注的就是bean的载入和初始话过程了。具体细节在后续的文章里面分析。