Spring 源码分析专题系列(X)深入认识 BeanPostProcessor 的原理

本文详细介绍了 Spring 中的 BeanPostProcessor,它提供了 Bean 初始化前后回调的方法,增强了框架的扩展性。文章通过源码分析了 Bean 的生命周期,展示了如何使用 BeanPostProcessor,并探讨了其与 @PostConstruct 的关系和执行顺序。同时,讨论了在注册多个 BeanPostProcessor 时的顺序问题以及 BeanPostProcessor 依赖 Bean 的特殊情况。
摘要由CSDN通过智能技术生成

前提概要

Spring 具有很好的扩展性,但是这个扩展它的这个扩展性体现在哪里呢?而我们要说的 BeanPostProcessor 就是对 Spring 扩展性优秀的表现之一。

🍃 BeanPostProcessor 的作用

  • 简单的说就是 BeanPostProcessor 提供了初始化前后回调的方法,我们所说的扩展就是在实例化前后对 Bean 进行扩展

  • BeanDefinition 注册完成之后进行注册,在创建 Bean 过程中的实例化前后分别调用其中定义的方法

其操作对象为:已经实例化且进行了属性填充,待初始化的 Bean 实例

🍃 源码分析


public interface BeanPostProcessor {
  /**
  * 初始前调用
  */
   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) 
	   throws BeansException {
      return bean;
   }
   /**
   * 初始化后调用
   */
   @Nullable
   default Object postProcessAfterInitialization(Object bean, String beanName) 
	   throws BeansException {
      return bean;
   }
}
  • 上面就是 BeanPostProcessor 接口的定义,从方法名字也能看出这两个方法一个在初始化前调用一个在初始化后调用。

  • 注意的是,方法的返回值为原始实例或者包装后的实例。如果返回 null 会导致后续的 BeanPostProcessor 不生效(BeanPostProcessor 是可以注册多个的)

🍃 如何使用

BeanPostProcessorDemo 代码如下:


public class BeanPostProcessorDemo {
    public static void main(String[] args) {
        //创建基础容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //加载xml配置文件
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions("spring-bean-post-processor.xml");
        //添加BeanPostProcessor
        beanFactory.addBeanPostProcessor(new UserBeanPostProcessor());
        User user = beanFactory.getBean(User.class);
        System.out.println(user);
    }
}
@Data
class User{
    private String userName;
    private Integer age;
    private String beforeMessage;
    private String afterMessage;
	
    public void initMethod(){
        System.out.println("初始化:"+this);
        this.setUserName("小明");
        this.setAge(18);
    }
}
class UserBeanPostProcessor implements BeanPostProcessor{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
		throws BeansException {
        if (bean instanceof User){
            System.out.println("初始化前:"+bean);
            ((User) bean).setBeforeMessage("初始化前信息");
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws 
		BeansException {
        if (bean instanceof User){
            System.out.println("初始化后:"+bean);
            ((User) bean).setAfterMessage("初始化后信息");
        }
        return bean;
    }
}

其他的省略......

运行之后打印结果如下:

初始化前:User(userName=null, age=null, beforeMessage=null, afterMessage=null)
初始化:User(userName=null, age=null, beforeMessage=初始化前信息, afterMessage=null)
初始化后:User(userName
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值