Spring BeanPostProcessor 接口总结

BeanPostProcessor在bean的生命周期中非常关键,应用程序可以根据自身特点自定义BeanPostProcessor来实现对bean定义的修改。除了BeanPostProcessor外,spring还提供了一些BeanPostProcessor的子接口来进一步增强对bean的扩展能力。BeanPostProcessor的子接口如下:

这些接口在bean的生命周期如下

java Process process 输出结果乱码_spring

BeanPostProcessor
// 在Bean实例化后,进行初始化前执行
Object postProcessBeforeInitialization(Object bean, String beanName);

// 在Bean实例化后,进行初始化后执行;如果被InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation短路,该方法也会被执行
Object postProcessAfterInitialization(Object bean, String beanName);

总结:

  • BeanPostProcessor提供两个基本的生命周期回调方法,这两个方法都是在Bean已经实例化后执行的。
  • postProcessBeforeInitialization在Bean实例化后、执行初始化前被调用,初始化是指执行开发者自定义的各种init方法。
  • postProcessAfterInitialization在Bean执行初始化方法后执行,并且该方法不同于其他BeanPostProcessor及其子类的回调方法,并不会因为InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation返回非空对象而被短路。
InstantiationAwareBeanPostProcessor
// 在bean被实例化前调用,如果返回一个非空bean则会短路后续bean的创建过程。
Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName);

// 在bean被实例化后、bean的属性被设置前调用,是执行自定义注入和属性设置的理想接口,如果接口返回false则会屏蔽掉spring的注入以及后续其他InstantiationAwareBeanPostProcessor的执行。
boolean postProcessAfterInstantiation(Object bean, String beanName);

// 在属性值被设置到bean的字段前执行,可以对PropertyValues进行修改。
PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName);

总结:

  • InstantiationAwareBeanPostProcessor继承自BeanPostProcessor,InstantiationAwareBeanPostProcessor顾名思义可以感知bean实例化的BeanPostProcessor,其主要作用是在bean实例化节点执行回调方法。
  • postProcessBeforeInstantiation在bean被实例化前调用,如果有非空返回值则会短路整个bean生命周期,后续只会执行BeanPostProcessor#postProcessAfterInitialization方法;通常可以在这里实现代理bean实现,比如spring aop的实现等。
  • postProcessAfterInstantiation在bean被实例化后调用,此时bean的属性并未被设置,所以可以执行自定义的bean属性的注入和设置;如果返回false则会spring会忽略后续的属性设置过程。
  • postProcessPropertyValues在属性值被设置到bean的字段前执行,可以对PropertyValues进行修改;如果postProcessAfterInstantiation返回false则该方法会被跳过。
SmartInstantiationAwareBeanPostProcessor
// 确定InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法返回bean的最终类型。
Class<?> predictBeanType(Class<?> beanClass, String beanName);

// 在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用,用于确定或者筛选合适的构造器。
Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName);

// 可以获取提前暴露的bean,主要用于解决bean之前的循环依赖问题。
Object getEarlyBeanReference(Object bean, String beanName);

总结:

  • SmartInstantiationAwareBeanPostProcessor继承自InstantiationAwareBeanPostProcessor接口,并提供3个新的方法。
  • predictBeanType用于确定当前SmartInstantiationAwareBeanPostProcessor方法postProcessBeforeInstantiation返回的实例的真正类型。
  • determineCandidateConstructors在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用,用于确定或者筛选合适的构造器并使用该构造器实例化bean。该方法可以被postProcessBeforeInstantiation短路。
  • getEarlyBeanReference主要用于解决bean之前的循环依赖问题,如果两个bean互相依赖,那么在实例化其中一个时需要提前将当前bean暴露出来,这样在填充其依赖时实例化另外一个实例,就可以通过该方法获取提前暴露的bean。
MergedBeanDefinitionPostProcessor
// 在MergedBeanDefinition实现之后,在bean属性被填充之前调用
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
  • MergedBeanDefinitionPostProcessor继承自BeanPostProcessor接口,用于在生成MergedBeanDefinition之后,实例化bean之后,填充bean属性之前,可以对MergedBeanDefinition进行扩展修改。
DestructionAwareBeanPostProcessor
// 在执行bean的销毁函数之前执行,比如DisposableBean#destroy方法
void postProcessBeforeDestruction(Object bean, String beanName);

// 用于确认当前DestructionAwareBeanPostProcessor是否应该执行,返回true表示应该执行
boolean requiresDestruction(Object bean);
  • DestructionAwareBeanPostProcessor继承自BeanPostProcessor接口,当bean在spring容器中被销毁前执行。

总结:Spring提供了丰富的bean扩展机制,这些机制符合设计模式开闭原则,即对扩展开放,对修改关闭。这些接口不仅仅只是给开发者扩展使用,在Spring自身的设计中都有丰富的应用场景,比如Spring AOP的实现,当需要对bean修改时我们也应该扩展对应的BeanPostProcessor,继承Spring这一优秀的设计原则。