【bean的生命周期】BeanPostProcessor简介


源码: https://github.com/nieandsun/spring-study


1 前言

通过前面两篇文章
【bean的生命周期】— 对象创建+初始化流程分析 — 【重点@Autowired的作用时机】
【bean的生命周期】— 构造方法、@Autowired、BeanPostProcessor、InitializingBean等的执行顺序解析
我已经从spring源码的角度介绍了BeanPostProcessor在单实例bean创建+初始化过程中的作用时机,本篇文章将对BeanPostProcessor的使用方法和原理做进一步剖析。


2 BeanPostProcessor简单介绍

2.1 BeanPostProcessor接口 + 运行时机介绍

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

前面两篇文章已经介绍过BeanPostProcessor的作用时机如下:
在这里插入图片描述
也就是说在每一个单实例业务bean的创建+初识化过程中,都会走当前IOC容器里所有实现了BeanPostProcessor接口的类的postProcessBeforeInitialization方法和postProcessAfterInitialization方法 —> 当然实现了BeanPostProcessor接口的bean是在更早的时机被注册到了IOC容器中。


2.2 BeanPostProcessor实现类简单介绍

spring源码里其实有很多实现了BeanPostProcessor接口的类,当然这些类并不会在spring启动时都一股脑的被注入到IOC容器里,除了一些必要的类之外,其他的类可以由使用者按需选择。
在这里插入图片描述


2.3 默认使用的BeanPostProcessor简单介绍

通过断点调试可以发现,针对单实例业务bean默认情况下spring注入到IOC容器中的BeanPostProcessor有如下几个:
在这里插入图片描述
每一个BeanPostProcessor对当前业务bean具体做了什么操作本文不做具体分析了 — 下篇文章应该会介绍一下ApplicationContextAwareProcessor,因为在工作中我们可能会经常遇到这个processor。


3 自定义BeanPostProcessor

通过上面的介绍可以知道BeanPostProcessor其实就是一个接口,当然我们也可以实现该接口,并将其注入到IOC容器,从而达到某些特定的目的。

3.1 自定义BeanPostProcessor并将其注入到IOC容器

  • 自定义BeanPostProcessor
package com.nrsc.springstudy.c072_bean_life_cycle.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component //通过扫描的方式将其注入到IOC容器
public class NrscBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("自定义后置处理器(前)---当前bean为:" + bean + ",beanName为:" + beanName);
        //返回处理后的bean --> 接下来该bean才能被注入到IOC容器
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("自定义后置处理器(后)---当前bean为:" + bean + ",beanName为:" + beanName);
        return bean;
    }
}
  • 业务bean — Cat
package com.nrsc.springstudy.c072_bean_life_cycle.beans;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
public class Cat implements InitializingBean {
    private String name;

    //构造方法-----创建对象时调用
    public Cat() {
        System.out.println("Cat......constructor............");
    }

    //设置name属性时会调用
    public void setName(String name) {
        System.out.println("===cat=========setName========");
        this.name = name;
    }

    public String getName() {
        return name;
    }

    //在配置类中利用注解将initMethod指向下面的init方法----对应于initMethod的用法
    public void init() {
        System.out.println("Cat......init............");
    }

    //继承了InitializingBean接口,需要实现afterPropertiesSet方法---对应于InitializingBean的用法
    public void afterPropertiesSet() throws Exception {
        System.out.println("Cat......afterPropertiesSet............");
    }

    @PostConstruct
    public void init2() {
        System.out.println("Cat......@PostConstruct............");
    }
}

3.2 测试

(1)可以发现自定义的BeanPostProcessor也起作用了
在这里插入图片描述
(2)运行结果如下:
在这里插入图片描述
由此也再一次验证了上篇文章中介绍的业务bean的创建+初始化过程中构造方法、@Autowired、BeanPostProcessor、@PostConstruct、InitializingBean、initMethod的执行顺序。


4 后话 — 介绍一个BeanPostProcessor的使用场景

其实在我之前的一篇博客里介绍过BeanPostProcessor的使用 —> 感觉那是一个比较好的BeanPostProcessor使用场景。那篇博客的地址为:《【Spring Security OAuth开发APP认证框架】— APP认证框架下社交登陆过程中注册逻辑处理》 。

发布了189 篇原创文章 · 获赞 187 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/nrsc272420199/article/details/103193183