第五讲:常见的BeanPostProcessor

2023-10-28

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

一、入门Demo

先准备了几个简单的类:

Bean01、Bean02什么都没有

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

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

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生效~~~~~");
    }
}

最后是入口方法的代码:


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()

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

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

在这里插入图片描述
可以看到,这三个注解生效了。

3. ConfigurationPropertiesBindingPostProcessor

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

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

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:

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

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

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第五讲:常见的BeanPostProcessor 的相关文章

随机推荐

  • Android Thread.UncaughtExceptionHandler捕获

    在Java 的异常处理机制中 如果抛出的是Exception异常的话 必须有try catch 进行处理 属于checked exception 如果抛出的是RuntimeException异常的话 则不是必须进行try catch 异常处
  • C++ 使用ffmpeg将本地视频推送到远程服务器

    1 包含必须的头文件 extern C include
  • Qt-国际化(语言切换)

    在Qt中 所有的输入部件和文本绘制方式对Qt支持的所有语言都提供了内置的支持 Qt内置的字体引擎可以在同一时间正确而且精细地绘制不同的文本 这些文本可以包含来自众多不同书写系统的字符 如果想了解更多的相关知识 可以在帮助中通过Overvie
  • 人工智能的动作来看这四家:百度、谷歌、微软、Facebook

    人工智能的动作来看这四家 百度 谷歌 微软 Facebook 人工智能已经成了兵家必争之地 但说句实在话 也都是准备的姿势 不过 瞭望未来的AI大战 积极的人才 设施 技术储备都是刚需 近日 美国 财富 杂志 Fortune 发表题为 Wh
  • 按键开关机电路

    1 目标 今天我们利用MOS管来设计一个按键开关机电路 2 要求 长按按键2秒钟松开后 系统电源启动 再长按2秒钟后 系统电源切断 3 分析 该电路设计的开始阶段应该是一个逻辑问题 后期器件选型以及参数确定才是一个硬件问题 下面只分析逻辑问
  • 各大AI开放平台汇总分析

    AI开放平台已经成为企业重要的基础设施 各大公司都建立了自己的AI开放平台 除了BAT 科大讯飞的建设的四大AI开放平台外 各公司纷纷推出了自己的人工智能平台 AI平台介绍和汇总如下 不断更新中 目录 百度AI开放平台 阿里云人工智能平台
  • 八步成功组织项目启动会议

    八步成功组织项目启动会议 项目启动会议将首次公布项目计划 这在很大程度上决定了项目是否能够圆满完成 你应该充分利用这个机会来给团队鼓劲 提出适当的期望 并根据时间和预算建立有助于项目顺利完成的指导方针 如果没有很好的准备项目启动会议 则会从
  • 电磁流量计测流工作原理及优缺点

    电磁流量计包含变送器和传感器 它们共同测量流量 电磁流量计的传感器采用直通连接 可测量流体在流经管道时产生的感应电压 变送器测量传感器产生的电压 将该电压转换成流量 然后再将流量测量值传送到控制系统 工作原理 电磁流量计是根据法拉第电磁感应
  • c 语言 模板函数,在 C 语言中实现模板函数的方法

    http blog csdn net whinah article details 13815 2004 各种用 C 语言实现的模板可能在使用形式上有所不同 现以一个求和函数 Sum 为例 用 C Template 可写如下 templat
  • 51单片机——独立按键

    如图是独立按键的原理图 通电后io口都是高电平 当按下K1 k4后 io口接地 变为低电平 说明当P30 P33为0时 代表我们按下了独立按键 例程1 独立按键控制LED亮灭 include
  • Matlab根据flac、pfc或其他软件导出的坐标及应力、位移数据再现云图

    Matlab根据flac pfc或其他软件导出的坐标及应力 位移数据再现云图 案例包括导出在flac6 0中导出位移的fish代码 也可以自己先准备软件导出的坐标数据及对应点的位移或应力数据 可根据需要自行修改为自己需要的云图数据 matl
  • 常用SQL语句

    一 基础1 说明 创建数据库CREATE DATABASE database name 2 说明 删除数据库drop database dbname3 说明 备份sql server 创建备份数据的 deviceUSE masterEXEC
  • 手机摄影_人像模式(双摄虚化Bokeh)

    很多人咨询我 手机上到底有哪些计算摄影的应用和技术 那么接下来就准备抽空写一系列文章做一下介绍 今天这一篇先从 人像模式 讲起 因为不管你现在是用iphone 还是小米 华为 OPPO VIVO 以及其他几乎所有品牌的手机 都已经能用这个功
  • 高仿“饿了么”Vue项目(一)

    高仿 饿了么 Vue项目 一 当我们把Vue框架的概念过了一遍之后 要进一步提升 就要看看别人是怎么使用Vue框架来做项目了 在github上有不少好的Vue项目 我找到了其中的一个 并把它作为下一步学习的目标 链接地址 https git
  • 使用docker/k8s部署vue项目

    使用docker k8s部署vue项目 1 编译前端项目 2 将前端文件打包 注意不要将dist目录打进去 自打dist里的文件 3 Dockerfile 本次打包将前端项目打入nginx镜像的html即可 FROM nginx MAINT
  • 最快捷方便的python安装库方法(适用于初学者)

    TOdfsa录标题 最快捷方便的python安装库方法 初学者 首先 当然我们首先已经安装好python以及其相关的环境配置 若是没有 当然也没有问题 我们可以从最初开始 详情请参考https www cnblogs com Coil177
  • 免费代理网址

    http www 66ip cn 66免费代理网 http www proxy360 cn Region China proxy360代理网 http www goubanjia com free gngn index shtml 转载于
  • MySQL-窗口函数&聚合函数

    从salaries表中查询emp no salary 并根据emp no字段升序累加salary作为running total字段 最后的结果如下图所示 MySQL语句如下 SELECT emp no salary SUM salary O
  • iOS 扩大UIView的点击范围原理

    扩大view点击范围的原理就是iOS的事件传递原理 事件从Window 上开始传递流程 首先执行window的hottest with event 方法 然后在该方法中会调用point inside 方法 判断点击点是否在 window中
  • 第五讲:常见的BeanPostProcessor

    常见的BeanPostProcessor 一 入门Demo 二 添加BeanPostProcessor 1 AutowiredAnnotationBeanPostProcessor 2 CommonAnnotationBeanPostPro