同前一篇一样,本文的分析还是基于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的载入和初始话过程了。具体细节在后续的文章里面分析。