BeanDefinitionRegistryPostProcessor[bean定义注册后置处理器]

此处理器,继承了BeanFactoryPostProcessor,
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor

作用时间点

Spring容器未进行bean定义(类信息)扫描前。

作用

获取BeanDefinitionRegistry对象,向Map中注册BeanDefinition对象

BeanFactoryPostProcessor[bean工厂后置处理器]

bean工厂处理器。

作用时间点

Spring容器完成bean定义(类信息)扫描,即类信息实体组装完成,但未进行实例化时

作用

解析Spring的配置类。利用此处理器可以修改bean定义实体信息。从而影响对应bean的实例化过程。
注:
类信息:是否懒加载、类名、类的作用域、等
bean定义使用实体beanDefinition存放,会放入beanDefinitionMap归集,类名为key
并且全类名放入beanDefinitionNames(ArrayList)集合

BeanPostProcessor[bean后置处理器]

bean处理器。

作用时间点

实例化时、属性赋值时,初始化时
BeanPostProcessor实例在bean(或对象)实例上运行。 即,Spring IoC容器实例化一个bean实例,然后才能用BeanPostProcessor 对这个实例进行处理。
后置处理器都会在容器初始化方法(如InitializingBean.afterPropertiesSet()之前和容器声明的init方法)以及任何bean初始化回调之后被调用。

作用

  1. - Spring容器**完成**实例化,配置和初始化bean**之后**实现某些自定义逻辑,则可以插入**一个或多个**BeanPostProcessor实现(可以通过设置**order属性**来控制BeanPostProcessor 实例的**执行顺序**)
  2. - BeanPostProcessor实例在bean(或对象)实例上运行。 即,Spring IoC容器实例化一个bean实例,然后才能用BeanPostProcessor 对这个实例进行处理。
  3. - BeanPostProcessor在整个容器容器内起作用,每一个BeanProcessor对容器中创建的每一个bean实例起作用。后置处理器可以对bean实例执行任何操作, 包括完全忽略回调

注:
仅当BeanPostProcessor实现 Ordered接口时,才能设置此属性。如果编写自己的BeanPostProcessor,则应考虑实现Ordered接口

BeanFactory与FactoryBean

BeanFactory是接口,给IOC容器实现,提供了规范。IOC容器核心接口
FactoryBean也是接口,为IOC容器中的Bean实现提供了更加灵活的方式。

BeanFactory

Spring顶层核心接口,使用简单的工厂模式,负责生产bean对象
包含访问配置文件、创建和管理bean以及进行IOC、DI操作的所有类。所有的bean都由BeanFactory管理
在Spring管理的类未实例化前,所有的类信息都归BeanFactory管理。
AnnotationConfigApplicationContext继承了BeanFactory
ApplicationContext接口,是由BeanFactory派生而来。
BeanFactory通过简单工厂模式(通过简单入参获取不同对象),从Map中读取bean定义,然后根据BeanDefinition(也是spring顶层接口,负责存储Class信息)信息进行bean对象生产

FactoryBean

通过BeanPostPorcessor来干涉Spring创建Bean的过程,(会将对应的)
FactoryBean是一个接口,当在IOC容器中的Bean实现FactoryBean后,通过getBean(String BeanName)
获取到的Bean对象并不是FactoryBean的实现类对应的对象,而是这个实现类中的getObject()方法返回的代理对象

获取对象过程

1.首次获取时,
1.1.调用getBean方法,得到FactoryBean实现类对象,并缓存到单例池(singletonObjects,key默认为首字符小写)
1.2.判断是否实现FactoryBean,实现,则进行强转直接调用getObject,执行用户自定义的实例化逻辑,获取指定实例对象。
1.3.并将获取的对象,缓存在factoryBeanObjectCache中(key与单例池相同)。
2.非首次获取
从factoryBeanObjectCache获取。
要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&(在单例池中获取)

FactoryBean接口提供下面三个方法

  1. - `Object getObject()`: 返回这个工厂创建的代理对象实例。这个实例可能是共享的,这取决于这个工厂返回的是单例还是原型实例。
  2. - `boolean isSingleton()`: 如果`FactoryBean`返回单例,那么这个方法就返回`true`,否则返回`false`
  3. - `Class getObjectType()`: 返回由`getObject()`方法返回的对象类型,如果事先不知道的类型则会返回null

应用场景

FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式
一般情况,Spring通过反射机制实例化bean,某些情况下,Spring配置实例化过程比较复杂,需要进行繁琐的配置,与其使用大量详细的XML,最好是使用Java语言来表达。
利用FactoryBean接口,用户可以使用java语言定制Bean实例化的过程。

与@Bean创建bean的区别

@Bean方式
自定义bean实例,与普通的bean生命周期一样,实例化、依赖注入、初始化前、初始化、初始化后(AOP)
FactoryBean方式
FactoryBean的实现类,是正常的完整的生命周期,而getObject方法中自定义的bean实例,仅进行初始化后动作,为了使getObject对象,支持AOP功能。

new AnnotationConfigApplicationContext.getBean(Demo.class)原理
实例会在Spring容器单例缓存池中获取。

bean生命周期中的扩展点