前言
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的实例化之前,实例化并调用所有已注册的BeanFactoryPostProcessor
Bean,如果实现了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 |