Spring拓展点之BeanPostProcessor

BeanPostProcessor是Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法

其接口定义如下:

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;
  }

在使用的时候,我们需要定义自己的实现类 

@Component
public class MyPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Before:bean:"+bean);
        System.out.println("Before:beanName:"+beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("After:bean:"+bean);
        System.out.println("After:beanName:"+beanName);
        return bean;
    }

}

此时启动spring,让我们看下控制台的打印输出

 可以发现每个bean的注册过程都调用了这两个回调方法

执行时机/bean初始化

BeanPostProcessor是对bean初始化方法作前置后后置处理(下面是bean的生命周期图)

定义bean的初始化方法,可以通过一个注解定义(下面代码中的init方法对应上图的 自定义init-method)

@Component("mybean")
public class MyBean implements InitializingBean {

    public MyBean(){
        System.out.println("我的构造函数执行了");
    }

    @PostConstruct
    public void init(){
        System.out.println("这是我的初始化方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("我在初始化方法后面");
    }
}

 @PostConstruct用于修饰返回值为void的非静态方法,标注该注解的方法会在bean实例化完成并且属性注入后进行调用,可以看下控制台打印

可以发现上面还有一个afterPropertiesSet方法,这个生命周期对应的是上图中的是否实现InitializingBean接口,如果实现便会调用其afterPropertiesSet方法

我们在定义BeanPostProcessor的实现类的时候,一般是针对某一类bean进行处理,因为所有bean都会调用其回调方法,所以我们需要在方法中进行一些判断(通过beanName或者bean的class类型去判断是否需要执行)如:

@Component
public class MyPostProcessor implements BeanPostProcessor {

    /**
     * bean初始化方法之前
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("mybean".equals(beanName)){
            System.out.println("初始化之前");
        }
        return bean;
    }

    /**
     * bean初始化方法之后
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("mybean".equals(beanName)){
            System.out.println("初始化之后");
        }
        return bean;
    }

}

源码解析

在spring源码中是将所有BeanPostProcessor实现类放在一个数组,依次调用其回调方法

  public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
        return result;
      }
      result = current;
    }
    return result;
  }

可以看到,它是将方法返回的对象当作result的,所以我们将传入的bean最后return出去(在上面可以看到一旦发现是null就会将result返回,这样后面的BeanPostProcessor的回调函数就没有执行)

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值