BeanFactory 作为Spring 中容器功能的基础,用于存放所有已经加载的bean,为了保证程序上的高可扩展性,Spring 针对BeanFactory做了大量的扩展,其中包括激活注册的BeanFactoryPostProcessor,注册BeanPostProcessor,初始化消息资源,初始化ApplicationEvenMulticaster,注册监听器.
激活注册的BeanFactoryPostProcessor
SpringIOC 除了可用使用BeanPostProcessor在实例化bean之前读取配置元数据,还可以使用BeanFactoryPostProcessor 在容器实际实例化任何其他bean之前读取配置元数据,并且可能修改它,如若需要还可以配置多个BeanFactoryPostProcessor,当BeanFactoryPostProcessor 实现了Ordered接口时,还可以通过设置"order"属性来控制BeanFactoryPostProcessor的执行次序.BeanFactoryPostProcessor 的作用域范围是容器级的,典型的应用是PropertyPlaceHolderConfigurer.
从PropertyPlaceholderConfigurer类层级结构图中可以看出,PropertyPlaceholderConfigurer 间接实现了BeanFactoryPostProcessor接口.当Spring加载任何实现了BeanFactoryPostProcessor接口的bean的配置时,都会在bean工厂载入所有bean的配置之后执行PostProcessorBeanFactory方法,在PropertyPlaceholderConfigurer 类中实现了PostProcessorBeanFactory方法,在方法中先后调用mergeProperties,processProperties方法,得到配置,将配置内容告知BeanFactory.
BeanFactoryPostProcessor 的处理主要分为两种情况进行,情况一是对于BeanDefinitionRegistry类的特殊处理,情况二是对普通的BeanFactoryPostProcessor进行处理,对于每种情况都需要考虑编码注入注册的后处理器以及通过配置注入的后处理器.激活BeanFactoryPostProcessor的源码如下:
注册BeanPostProcessor
Spring中大部分功能都是通过后处理器的方式进行扩展的, 但是在BeanFactory 中其实并没有实现处理器的方式进行扩展,所以在调用的时候如果没有进行手动注册其实是不能使用的. 但是在ApplicationContext 中添加了自动注册功能, 自动注册功能由PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this) 来实现,源码如下:
对于BeanPostProcessor的处理与BeanFactoryPostProcessor的处理极为相似,但又有些不同,BeanFactoryPostProcessor的处理区分为两种,一种方式是通过硬编码方式的处理,另一种是通过配置文件方式的处理.而BeanPostProcessor的处理方式只考虑了配置文件的方式.是因为BeanPostProcessor不需要马上调用,只需要将配置文件的BeanPostProcessor提取出来并注册进入BeanFactory就可以了,而且在registerBeanPostProcessors()方法中已经确保了beanPostProcessor的唯一性.
初始化消息资源
Spring 定了访问国际化信息的MessageSource接口,提供了3个易用的实现类,如下图.
MessageSource 分别被HierarchicalMessageSource 和ApplicationContext接口扩展,如下图:
HierarchicalMessageSource接口最重要的两个实现类是ResourceBundleMessageSource和ReloadableResourceBundleMessageSource。它们基于Java
的ResourceBundle基础类实现,允许仅通过资源名加载国际化资源。ReloadableResourceBundleMessageSource提供了定时刷新功能,允许在不重启系统的情况下, 更新资源的信息。StaticMessageSource 主要用于程序测试,它允许通过编程的方式提供国际化信息。而DelegatingMessageSource 是为方便操作父MessageSource而提供的代理类.
在initMessageSource中的方法主要功能是提取配置中定义的messageSource,并将其记录在Spring容器中,在initMessageSource中获取自定义资源文件的方式为beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class),此处Spring使用了硬编码的方式硬性规定了自定义资源文件必须为message,否则便会获取不到自定义资源配置.initMessageSource()源码如下:
通过读取并将自定义资源文件配置记录在容器中,那么就可以在获取资源文件的时候直接使用了.
初始化ApplicationEvenMulticaster
initApplicationEventMulticaster 采用的是观察者模式,考虑两种情况:
- 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器,
- 如果用户没有自定义事件广播器,那么默认的ApplicationEventMulticaster.
源码如下:
当产生Spring 事件的时候会默认使用SimpleApplicationEventMulticaster 的multicastEvent 来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent 方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器来决定。