一、BeanFactory和ApplicationContext的区别
1.BeanFacotry接口
负责生产和管理bean的一个工厂。
是Spring容器的顶层接口,提供了 IOC 容器应遵守的的最基本的接口
它有多种实现:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等
但它是spring中比较原始的Factory无法支持spring的许多插件,如AOP功能、Web应用等。
2.ApplicationContext接口
它由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通过@Service等注解进行Bean实例化的配置,但是在某些情况下(比如在Bean实例化时)需要大量的配置信息,默认的Bean实例化机制是无能为力的。
为此,Spring提供了一个org.springframework.bean.factory.FactoryBean工厂接口,用户可以通过该接口在Java代码中实现定制Bean实例化的逻辑。
FactoryBean在Spring框架中占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。
它们隐藏了一些复杂Bean实例化的细节,给上层应用带来了便利。
FactoryBean注册到容器之后,从Spring上下文通过ID或者类型获取IOC容器Bean时,获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身。
首先它是一个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注解的注入