前言
ApplicationContext实现了除基本容器外的多个接口,提供了比BeanFactory更为丰富的功能,比如说自动识别BeanPostProcessor以及其它特殊类型Bean、容器启动时自动加载Bean、国际化支持、容器内事件发布等。因此,我们在实际应用中一般会使用ApplicationContext而不是BeanFactory。
继承体系

从上图可以看出,ApplicationContext继承了BeanFactory,因此拥有BeanFactory的全部功能,实际上,它是将容器的功能委派给DefaultListableBeanFactory来实现。除此之外,ApplicationContext还继承了ResourceLoader、EnvironmentCable、ApplicationEventPublisher、MessageSource等接口,提供了十分丰富的功能。
源码分析
创建一个常用的ApplicationContext:1
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
ClassPathXmlApplicationContext的构造函数在设置完配置文件的位置后,紧接着调用refresh()方法,这个方法是整个ApplicationContext体系的核心,是在AbstractApplicationContext中实现的,并且是个典型的模板方法,也就是说其中的一些步骤是交由具体子类来实现的。以下是这个方法的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新时的上下文环境
prepareRefresh();
// 2. 刷新并初始化 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 配置 BeanFactory 中的一些其它信息
prepareBeanFactory(beanFactory);
try {
// 4. 提供子类覆盖的额外处理,即子类处理自定义的 BeanFactoryPostProcess
postProcessBeanFactory(beanFactory);
// 5. 调用各种 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor 到 BeanFactory 中去
registerBeanPostProcessors(beanFactory);
// 7. 初始化上下文中的资源文件,如国际化文件的处理等
initMessageSource();
// 8. 初始化上下文事件广播器
initApplicationEventMulticaster();
// 9. 初始化其它特殊 Bean
onRefresh();
// 10. 检查 listener 类型的 Bean 并注册
registerListeners();
// 11. 实例化所有非懒加载的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
// ...
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
obtainFreshBeanFactory
obtainFreshBeanFactory()方法核心是内部调用refreshBeanFactory()方法并将容器内部的ConfigurableListableBeanFactory返回,从这也看到了ApplicationContext和BeanFactory的关系:ApplicationContext内部包含一个BeanFactory,ApplicationContext所有关于BeanFactory的功能将委派给此BeanFactory处理。
1 | protected final void refreshBeanFactory() throws BeansException { |
也就是说这一步是构建ApplicationContext内部的BeanFactory,以及根据配置将BeanDefinition加载到BeanFactory中(此时并没有实例化Bean)。
prepareBeanFactory
配置内部BeanFactory的一些基础参数,比如ClassLoader等等。
postProcessBeanFactory
对BeanFactory预处理,ClassPathXmlApplicationContext未重写,WebXmlApplicationContext有重写,这里不展开。
invokeBeanFactoryPostProcessors
在任何Bean的实例化之前,实例化并调用所有已注册的BeanFactoryPostProcessorBean,如果实现了PriorityOrdered或者Ordered接口则按顺序调用。此时允许BeanFactoryPostProcessor在实例化BeanDefinition之前对当前的配置数据进行修改。
registerBeanPostProcessors
将当前所有的BeanPostProcessor注册到BeanFactory中去,同样也是按照PriorityOrdered或者Ordered的顺序。这也是ApplicationContext与BeanFactory的一个不同,BeanFactory必须自己手动的调用addBeanPostProcessor()方法。
initMessageSource
初始化MessageSource,如果没有定义则使用DelegatingMessageSource,实际是委派给父类的。
initApplicationEventMulticaster
初始化ApplicationEventMulticaster,如果没有定义则使用SimpleApplicationEventMulticaster。
onRefresh
模板方法,交给子类来实现,一般是用于在实例化单例Bean之前调用特定Bean的初始化。
registerListeners
将所有ApplicationListener注册到ApplicationEventMulticaster中,然后将earlyApplicationEvents中定义的事件进行广播。
finishBeanFactoryInitialization
实例化所有剩余的非懒加载的单例Bean,就是遍历所有的beanName,然后挨个调用getBean(beanName)。
finishRefresh
完成此上下文的刷新,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent。主要是对于有生命周期的Bean,按照分组,调用其start()方法。
ApplicationContext使用
1 | // beanFactory |