【二十】Spring IOC 总结之BeanFactory、ApplicationContext、BeanFactoryPostProcessor、BeanPostProcessor区别

一、BeanFactory和ApplicationContext的区别

1.BeanFacotry接口

【二十】Spring IOC 总结之BeanFactory、ApplicationContext、BeanFactoryPostProcessor、BeanPostProcessor区别

负责生产和管理bean的一个工厂。

是Spring容器的顶层接口,提供了 IOC 容器应遵守的的最基本的接口

它有多种实现:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等

但它是spring中比较原始的Factory无法支持spring的许多插件,如AOP功能、Web应用等。 

2.ApplicationContext接口

【二十】Spring IOC 总结之BeanFactory、ApplicationContext、BeanFactoryPostProcessor、BeanPostProcessor区别

它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。

此外,因ApplicationContext还继承了一些其他接口(具体看上图),所以它还提供了以下的功能,而这些功能是BeanFacotry接口没有的: 

1.利用MessageSource进行国际化 

由于ApplicationContext扩展了MessageResource接口,因而具有消息处理的能力(i18N)

2.资源访问,如URL和文件  

ApplicationContext扩展了ResourceLoader(资源加载器)接口,从而可以用来加载多个Resource

3.强大的事件机制(Event)  

ApplicationContext的事件机制主要通过ApplicationEventPublisher来提供的

4.载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web

其它区别  

  1.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 

  2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册 

  3.BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

二、FactoryBean

【二十】Spring IOC 总结之BeanFactory、ApplicationContext、BeanFactoryPostProcessor、BeanPostProcessor区别

首先它是一个Bean,但又不只是一个Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似 .

spring中最为典型的一个应用就是ProxyFactoryBean用来创建AOP的代理对象。

FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象

要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

比如:

getBean('name')返回工厂中的实例,即是getObject()方法返回的对象

getBean('&name')返回FactoryBean本身的实例

三、BeanFactoryPostProcessor与BeanPostProcessor

1.BeanFactoryPostProcessor

BeanFactoryPostProcessor 为spring在容器初始化时对外对外暴露的扩展点

Spring IoC容器允许BeanFactoryPostProcessor在容器加载注册BeanDefinition完成之后读取BeanDefinition(配置元数据),并可以修改它

ApplicationContext可以在其bean定义中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前先创建BeanFactoryPostProcessor

BeanFactoryPostProcessor可以与bean定义交互并修改BeanDefinition,但绝不能与bean实例交互。如果在这里就去触发Bean的实例化会有两个副作用:参考使用BeanFactoryPostProcessor——这种姿势不要用

1.使用注解进行依赖注入失败

2.可能会将ApplicationContext容器启动过程暴露在多线程之下

如果需要bean实例交互,应考虑实现BeanPostProcessor。

实现BeanFactoryPostProcessor接口,可以允许我们的程序获取到BeanFactory,从而修改BeanFactory,可以实现编程式的往Spring容器中添加Bean。

在Spring中ConfigurationClassPostProcessor这个BeanFactoryPostProcessor尤其重要。它会定位资源、加载解析BeanDefinition,注册BeanDefinition

关于ConfigurationClassPostProcessor详情请看前面的两篇文章:

【十九】Spring IOC 总结之启动时定位资源和BeanDefinition载入、解析、注册(SpringBoot 扫启动类所在包、starter、@Import)

【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法

这里再推荐一篇我觉得讲得很好的spring之BeanFactoryPostProcessor执行流程 

2.BeanPostProcessor

BeanPostProcessor是在getBean的时候,作用于bean的生命周期,比如实例化阶段、初始化阶段

详情看以前的一篇:【十八】Spring IOC 总结之getBean主流程和各个扩展点总结

有几个重要的BeanPostProcessor实现类需要关注一下

1.MergedBeanDefinitionPostProcess : 合并bean定义

2.AbstractAutoProxyCreator : 生成AOP代理的

3.ApplicationContextAwareProcessor :用来为bean注入ApplicationContext等容器对象,会调用这几种Aware的实现

EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware

4.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入

5.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入

6.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入

7.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入