#概述
|
|
#1. 加载BeanFactory
经过obtainFreshBeanFactory()
之后,ApplicationContext就已经拥有了BeanFactory的全部功能
|
|
- 创建DefaultListableBeanFactory
- 执行序列化ID
- 定制BeanFactory
- 加载BeanDefinition
- 使用全局变量记录BeanFactory实例
##定制BeanFactory
增加是否允许覆盖,是否允许扩展的设置(通过子类覆盖)
##加载BeanDefinition
初始化DefaultListableBeanFactory之后需要XmlBeanDefinitionReader来读取XML,接下来是初始化XmlBeanDefinitionReader的步骤
在初始化完DefaultListableBeanFactory和XmlBeanDefinitionReader后就可以进行配置文件的读取了。
#2. 功能扩展
在进入函数 prepareBeanFactory 前,Spring 已经完成了对配置的解析,而 ApplicationContext 在功能上的扩展也由此展开。
上面函数主要进行了几个方面的扩展:
- 增加对SPEL语言的支持
- 增加对属性编辑的支持
- 增加一些对内置类,比如EnvironmentAware,MessageSourceAware的信息注入
- 设置了依赖功能可忽略的接口
- 注册一些固定依赖的属性
- 注册ApplicationListenerDetector
- 增加AspectJ的支持
- 将相关环境变量及属性注册以单例模式注册
##添加 ApplicationContextAwareProcessor 处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
这行代码的主要目的是注册一个BeanPostProcessor
,而真正的逻辑还是在ApplicationContextAwareProcessor
中
ApplicationContextAwareProcessor
实现BeanPostProcessor
接口
这个Processor
的作用在于为实现*Aware
接口的bean调用该Aware接口定义的方法,并传入对应的参数。比如实现EnvironmentAware
接口的bean在该Processor内部会调用EnvironmentAware
接口的setEnvironment
方法,并把Spring容器内部的ConfigurableEnvironment
传递进去。
这里关注下ApplicationContextAwareProcessor的实现BeanPostProcessor的postProcessBeforeInitialization方法。
|
|
设置忽略依赖
invokeAwareInterfaces
方法中间接调用的 Aware
类已经不是普通的 bean 了,如 ResourceLoaderAware
、ApplicationEventPublisherAware
等,那么当然需要在 Spring 做 bean 的依赖注入的时候忽略它们。而 ignoreDependencyInterface
的作用正是在此。
|
|
注册依赖
|
|
当注册了依赖解析后,例如当注册了对 BeanFactory.class
的解析依赖后,当 bean 的属性注入的时候,一旦检测到属性为 BeanFactory
类型便会将 beanFactory
的实例注入进去。
#3. BeanFactory的后处理
4. 激活注册的BeanFactoryPostProcessor
BeanFactoryPostProcessor
接口跟 BeanPostProcessor
类似,可以对 bean 的定义(配置元数据)进行处理。也就是说,Spring IoC 容器允许 BeanFactoryPostProcessor
在容器实际实例化任何其他的 bean 之前读取配置元数据,并有可能修改它。如果你愿意,你可以配置多个 BeanFactoryPostProcessor
。你还能通过设置 order 属性来控制 BeanFactoryPostProcessor
的执行次序(仅当 BeanFactoryPostProcessor
实现了Ordered
接口时你才可以设置此属性,因此在实现 BeanFactoryPostProcessor
时,就应当考虑实现 Ordered
接口)。
如果你想改变实际的bean实例(如从配置元数据创建的对象),那么你最好用BeanPostProcessor。同样地,BeanFactoryPostProcessor
的作用域范围是容器级的。它只和你所使用的容器有关。如果你在容器中定义一个 BeanFactoryPostProcessor
,它仅仅对此容器中的 bean 进行后置处理。BeanFactoryPostProcessor
不会对定义在另一个容器中的 bean 进行后置处理,即使这两个容器都是在同一层次上。
BeanFactoryPostProcessor的典型应用:PropertyPlaceholderConfigurer
指定配置文件使用
PropertyPlaceholderConfigurer
这个类间接继承了BeanFactoryPostProcessor接口。这是一个很特别的接口,当Spring加载任务实现了这个接口的bean的配置时,都会在bean工厂载入所有bean配置之后执行postProcessBeanFactory()方法。在PropertyResourceConfigurer类中实现了postProcessBeanFactory
方法,在方法中先后调用了mergeProperties()
、convertProperties()
、processProperties()
这3个方法,分别得到配置,将得到的配置,将得到的配置转换为合适的类型,最后将配置内容告知 BeanFactory
。
lawsuit中也使用了这个bean
|
|
##激活 BeanFactoryPostProcessor
|
|
|
|
对于BeanFactoryPostProcessor的处理主要分为两种情况进行:一个是对于BeanDefinitionRegistry类的处理,量一种是对于普通BeanFactoryPostProcessor进行处理。而对于每种情况都需要考虑硬编码注入注册的后处理器以及通过配置注入的后处理器
对于BeanDefinitionRegistry类型的处理类的处理主要包括以下内容:
- 对于硬编码注册的后处理器的处理,主要是通过
AbstractApplicationContext
中的添加处理器方法addBeanFactoryPostProcessor
进行添加。- 添加后的处理器会存放入
beanFactoryPostProcessors
中,而在处理BeanFactoryPostProcessor
时候会首先检测beanFactoryPostProcessor
是否有数据。当然,BeanDefinitionRegistryPostProcessor
继承自BeanFactoryPostProcessor
,不但有BeanFactoryPostProcessor
的特性,同时还有自己定义的个性化方法,也需要在此调用。所以,这里需要从beanFactoryPostProcessors
中挑出BeanDefinitionRegistryPostProcessor
的后处理器,并进行其postProcessBeanDefinitionRegistry
方法的激活。
- 添加后的处理器会存放入
- 记录后处理器主要使用了三个List完成:
- registryPostProcessors:记录通过硬编码方式注册的BeanDefinitionRegistryPostProcessor类型的处理器
- regularPostProcessors:记录通过硬编码方式注册的BeanFactoryPostProcessor类型的处理器
- 对于以上所记录的list中的后处理器统一调用BeanFactoryPostProcessor的postProcessBeanFactory()方法
- 对
beanFactoryPostProcessors
中非BeanDefinitionRegistryPostProcessor
类型的后处理器进行统一的BeanFactoryPostProcessor
的postProcessBeanFactory
方法调用。 - 普通beanFactory处理
5. 注册BeanPostProcessor
真正的调用是在bean的实例化阶段进行的
|
|
PostProcessorRegistrationDelegate:Delegate for AbstractApplicationContext’s post-processor handling.
|
|
对于 BeanFactoryPostProcessor
的处理,不但要实现注册功能,而且还要实现对后处理器的激活操作,所以需要载入配置中的定义,并进行激活;而对于 BeanPostProcessor
并不需要马上调用,再说,硬编码的方式实现的功能是将后处理器提取并调用,这里并不需要调用,当然不需要考虑硬编码的方式了,这里的功能只需要将配置文件的 BeanPostProcessor
提取出来并注册进入 beanFactory 就可以了。
6. 初始化ApplicationEventMulticaster
initApplicationEventMulticaster
的方式比较简单,无非考虑两种情况。
- 如果用户自定义了事件广播器,那么使用用户自定义的时间广播器
- 如果用户没有自定义事件广播器,那么使用默认的
ApplicationEventMulticaster
|
|
由此推断其中默认实现的广播器 SimpleApplicationEventMulticaster
中有逻辑来存储监听器并在合适的时候调用。
|
|
可以推断,当产生 Spring 事件的时候会默认使用 SimpleApplicationEventMulticaster
的 multicastEvent
来广播事件,遍历所有监听器,并使用监听器中的 onApplicationEvent
方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。
7. 注册监听器
|
|
#8. 初始化非延迟加载单例
完成BeanFactory的初始化工作,其中包括ConversionService的设置、配置冻结以及非延迟加载的bean的初始化
|
|
初始化非延迟加载
ApplicationContext实现的默认行为就是在启动时将所有单例进行提前实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有单例bean。通常情况下这是一件好事,因为这样在配置中的任何错误就会即刻被发现。而这个实例化过程就是在finishBeanFactoryInitailization中完成的。
|
|
9. finishRefresh
在Spring中还提供了Lifecycle接口,Lifecycle中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始声明周期,并在Spring关闭的时候调用stop方法来结束声明周期,通常用来配置后台程序,在启动后一直运行(如对MQ的轮询等)。而ApplicationContext的初始化最后正是保证了这一功能的实现
|
|
##initLifecycleProcessor
当 ApplicationContext 启动或停止时,它会通过 LifecycleProcessor 来与所有声明的 bean 的周期做状态检查,而 LifecycleProcessor 的使用前首先需要初始化。
|
|
##onRefresh
启动所有实现了 Lifecycle 接口的 bean
|
|
|
|
##publishEvent
当完成 ApplicationContext 初始化的时候,要通过 Spring 中的事件发布机制来发出 ContextRefreshedEvent 事件,以保证对应的监听器可以做进一步的逻辑处理。
|
|
registerApplicationContext
注册 LiveBeansView MBean(如果处于活动状态)
关于 LiveBeansView:
Adapter for live beans view exposure, building a snapshot of current beans and their dependencies from either a local
ApplicationContext
(with a localLiveBeansView
bean definition) or all registered ApplicationContexts (driven by the “spring.liveBeansView.mbeanDomain” environment property).
|
|