第五讲:常见的BeanPostProcessor

常见的BeanPostProcessor

  • 一、入门Demo
  • 二、添加BeanPostProcessor
    • [1. AutowiredAnnotationBeanPostProcessor](#1. AutowiredAnnotationBeanPostProcessor)
    • [2. CommonAnnotationBeanPostProcessor](#2. CommonAnnotationBeanPostProcessor)
    • [3. ConfigurationPropertiesBindingPostProcessor](#3. ConfigurationPropertiesBindingPostProcessor)

前文我们简单讲了Bean的生命周期,以及生命周期的前后,本文将解释生命周期中的一些注解是怎么生效。

一、入门Demo

先准备了几个简单的类:

Bean01、Bean02什么都没有

java 复制代码
public class Bean01 {
	public Bean01() {
        System.out.println("Bean01实例化~~~~~");
    }
}
java 复制代码
public class Bean02 {
	public Bean02() {
        System.out.println("Bean02被实例化~~");
    }
}

Bean03Bean01、Bean02 分别通过@Autowired@Resource注入,为了测试@Value时能打印日志,因此使用了这种方式注入,上篇文章有同样的用法,这边不再解释。

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class Bean03 {

    private Bean01 bean01;

    private Bean02 bean02;

    private String home;

    public Bean03() {
        System.out.println("Bean03被实例化~~~~");
    }

    @Autowired
    private void setBean01(Bean01 bean01) {
        this.bean01 = bean01;
        System.out.println("@autowired生效~~~~" + bean01);
    }

    @Resource
    private void setBean02(Bean02 bean02) {
        this.bean02 = bean02;
        System.out.println("@Resource生效~~~" + bean02);
    }

    @Autowired
    private void setHome(@Value("${JAVA_HOME}") String home) {
        this.home = home;
        System.out.println("@Value生效" + home);
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct生效~~~~~");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("@PreDestroy生效~~~~~");
    }
}

最后是入口方法的代码:

java 复制代码
import com.linqibin.spring.component.Bean01;
import com.linqibin.spring.component.Bean02;
import com.linqibin.spring.component.Bean03;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;

/**
 * 测试往容器中添加一些Bean后置处理器时的作用
 *
 * @Date 2023/8/22 21:51
 */
public class TestProcessors {

    public static void main(String[] args) {
        // 通用ApplicationContext,这是一个比较【干净】的容器,可以用来测试手动添加后置处理器的效果
        GenericApplicationContext context = new GenericApplicationContext();

        // 往容器中添加三个Bean,默认是单例的,其中Bean03比较复杂,Bean01、Bean02中什么也没有
        context.registerBean("bean01", Bean01.class);
        context.registerBean("bean02", Bean02.class);
        context.registerBean("bean03", Bean03.class);

        // 初始化容器(也就是让ApplicationContext帮我们去执行BeanFactory的一系列流程)
        context.refresh();
        // 关闭容器
		context.close();

    }
}

这边我们使用的是GenericApplicationContext,因为这个容器比较干净,其他的容器里面默认添加了一些BeanPostProcessor,不方便我们测试。执行main()

Bean03里面我们不是添加了很多东西吗?为什么就构造方法被执行了?

二、添加BeanPostProcessor

Spring在创建Bean的时候是通过各种Bean的后置处理器去管理Bean的生命周期 ,因此里面的各种依赖注入、初始化方法执行、销毁方法执行都是通过BeanPostProcessor生效的。

1. AutowiredAnnotationBeanPostProcessor

根据名字我们就能看出来,这个后置处理器的作用就是来处理@Autowired的,我们将他添加进main()

java 复制代码
public static void main(String[] args) {
        // 通用ApplicationContext,这是一个比较【干净】的容器,可以用来测试手动添加后置处理器的效果
        GenericApplicationContext context = new GenericApplicationContext();

        // 往容器中添加三个Bean,默认是单例的,其中Bean03比较复杂,Bean01、Bean02中什么也没有
        context.registerBean("bean01", Bean01.class);
        context.registerBean("bean02", Bean02.class);
        context.registerBean("bean03", Bean03.class);

        // >>>>>>>>>添加BeanPostProcessor<<<<<<<<<<

        // 因为涉及到注入String对象,所以需要换掉候选解析器(先看个眼熟,后续讲)
        context.getDefaultListableBeanFactory().setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        // 添加后,@Autowired、@Value会生效
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);

        // 初始化容器(也就是让ApplicationContext帮我们去执行BeanFactory的一系列流程)
        context.refresh();
        context.close();


    }

因为涉及到注入String------Bean03的setHome(),所以需要换掉候选解析器(混个眼熟,后续讲)。

可以看到,Bean03实例化后,@Value@Autowired都生效了,都成功注入属性了。

2. CommonAnnotationBeanPostProcessor

这个后置处理器是添加javax包下的一些注解的处理,如@Resource@PostConstruct@PreDestroy

java 复制代码
	// 添加后,@Resource、@PostConstruct、@PreDestroy会生效
    context.registerBean(CommonAnnotationBeanPostProcessor.class);

可以看到,这三个注解生效了。

3. ConfigurationPropertiesBindingPostProcessor

这个处理器是SpringBoot才有的,用来处理@ConfigurationProperties

先添加Bean04,是一个配置属性类(因为java.home,java.version环境变量中有,因此不需要额外添加):

java 复制代码
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 测试ConfigurationProperties
 *
 * @Author linqibin
 * @Date 2023/8/22 23:14
 * @Email 1214219989@qq.com
 */
@Data
@ConfigurationProperties(prefix = "java")
public class Bean04 {
    
    private String home;
    
    private String version;
}

main()中添加bean04,然后刷新容器,并打印bean04:

java 复制代码
	// 添加后,@ConfigurationProperties会生效
       ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
       context.registerBean("bean04", Bean04.class);

       // 初始化容器(也就是让ApplicationContext帮我们去执行BeanFactory的一系列流程)
       context.refresh();
       System.out.println(context.getBean("bean04"));
相关推荐
海边漫步者13 分钟前
Idea2024中搭建JavaFX开发环境并创建运行项目
java·intellij-idea·javafx
diemeng111919 分钟前
2024系统编程语言风云变幻:Rust持续领跑,Zig与Ada异军突起
开发语言·前端·后端·rust
Warren9823 分钟前
Springboot中分析SQL性能的两种方式
java·spring boot·后端·sql·mysql·intellij-idea
软件黑马王子33 分钟前
Unity游戏制作中的C#基础(3)加减乘除算术操作符,比较运算符,逻辑与,或运算符
开发语言·unity·c#
张太行_34 分钟前
Qt Creator 设计界面后的预览方法
开发语言·qt
视觉CG38 分钟前
【Viewer.js】vue3封装图片查看器
开发语言·javascript·vue.js
h^hh44 分钟前
洛谷 P3405 [USACO16DEC] Cities and States S(详解)c++
开发语言·数据结构·c++·算法·哈希算法
qwy7152292581631 小时前
20-R 绘图 - 饼图
开发语言·数据库·r语言
重生之我要成为代码大佬1 小时前
Python天梯赛10分题-念数字、求整数段和、比较大小、计算阶乘和
开发语言·数据结构·python·算法
琑951 小时前
nextjs项目搭建——头部导航
开发语言·前端·javascript