ClassPathXmlApplicationContext是应用的起点,通常调用下面的构造函数,参数为配置文件的地址
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, (ApplicationContext)null);
}
创建一个classpathXmlApplicationContext对象时,初步分2步,设置配置文件地址,启动应用。
this.setConfigLocations(configLocations);
this.refresh(); //调用父类AbstractApplicationContext
refresh()解析:
- 第一步,prepareRefresh();非web应用,只是初始化了一些变量(closed,active)的值
- 第二步,obtainFreshBeanFactory();创建beanFactory.
refreshBeanFactory(),刷新beanFactory,如果已经有,
destroyBeans(),closeBeanFactory()。
createBeanFactory(),直接使用context的id作为新beanFactory的id。
this.loadBeanDefinitions(beanFactory); - 第三步,
第二步:
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();//基本设置,可以忽略
//创建DefaultListableBeanFactory,设置ID为applicationContext的id
//loadBeanDefinitions,加载bean的定义,
//把所有的bean定义加载到Map<String, BeanDefinition> beanDefinitionMap
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//注册一些依赖的bean
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
--- 虚线内为其它方法
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//添加到beanPostProcessors中,这是 一个list
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
//添加到ignoredDependencyInterfaces,这是一个set
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
//注册request,session,globalSession,application四个scope到beanFactory的scopes(这是一个map)中,ServletRequest,ServletResponse,HttpSession等(factory型的)注册到resolvableDependencies(也是map)中
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
//注册servletContext,servletConfig,contextParameters,contextAttributes等到spring容器中
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
---
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
//创建一个messageSource到容器中
this.initMessageSource();
//创建applicationEventMulticaster到容器中
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
//这里会实例化所有非延迟加载的bean实例
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();
}
}
}
其中obtainFreshBeanFactory();调用XmlWebApplicationContext的loadBeanDefinitions,一路下去,直到XmlBeanDefinitionReader的loadBeanDefinitions,也就是第三篇的核心内容。这条线,作用就是解析配置文件,把符合条件的beanDefinition注册到factory中。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
return this.getBeanFactory();
}
在refreshBeanFactory();中,先判断有没有beanfactory,有的话,先去除引用。
if(this.hasBeanFactory()) {
this.destroyBeans();//第十七篇中
this.closeBeanFactory();//beanFactory置为null,id置为null。serializableFactories(静态常量,DefaultListableBeanFactory的)中移除这个beanfactory的弱引用。
}
创建一个DefaultListableBeanFactory实例,如果有parent,则把parent的bf也传递过来。
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
给bf一个id,采用的系统默认hashcode实现,所以对于这个对象基本上不会重复。然后会把bf放到一个static的map中,使用弱引用包裹。
beanFactory.setSerializationId(this.getId());
AbstractRefreshableApplicationContext的loadBeanDefinitions(beanfactory),这是关键方法,在其他篇中详解
至此,AbstractRefreshableApplicationContext的refreshBeanFactory解析完毕,getBefactory获得的也是这个factory。