第五讲:常见的BeanPostProcessor

news2024/11/22 22:08:41

常见的BeanPostProcessor

  • 一、入门Demo
  • 二、添加BeanPostProcessor
    • 1. AutowiredAnnotationBeanPostProcessor
    • 2. CommonAnnotationBeanPostProcessor
    • 3. ConfigurationPropertiesBindingPostProcessor

前文我们简单讲了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"));

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/914269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科大讯飞AI大模型,太猛了!

最近几个月&#xff0c;以ChatGPT为代表的AIGC迅速崛起&#xff0c;国内头部科技企业之间也掀起了百模大战&#xff0c;在众多的大模型当中我比较看好的一家就是&#xff1a;科大讯飞。 我很早就通过科大讯飞老朋友&#xff0c;拿到了体验账号&#xff0c;简单体验了一下&…

C++新经典06-- 语言特性

1.继承性、多态性、封装性。 2.C本身是属于编译型语言。 什么叫编译型语言呢&#xff1f;程序在执行之前需要一个专门的编译过程&#xff0c;把程序编译成二进制文件&#xff08;可执行文件&#xff09;&#xff0c;执行的时候&#xff0c;不需要重新翻译&#xff0c;直接使用…

shell脚本中linux命令的特殊用法记录

shell脚本中linux命令的特殊用法记录 1、linux命令特殊参数选项1.1、sed -e1.2、echo -e 2、 shell 扩展2.1、[[ ]]支持用~进行正则匹配 3、特殊命令用法3.1、{} 变量替换 1、linux命令特殊参数选项 1.1、sed -e sed -e以严格模式执行脚本&#xff0c;在sed -e 后面的所有命令…

反转链表II

江湖一笑浪滔滔&#xff0c;红尘尽忘了 题目 示例 思路 链表这部分的题&#xff0c;不少都离不开单链表的反转&#xff0c;参考&#xff1a;反转一个单链表 这道题加上哨兵位的话会简单很多&#xff0c;如果不加的话&#xff0c;还需要分情况一下&#xff0c;像是从头节点开始…

【Apollo学习笔记】——规划模块TASK之PATH_BORROW_DECIDER

文章目录 前言PATH_BORROW_DECIDER功能简介PATH_BORROW_DECIDER相关配置PATH_BORROW_DECIDER总体流程PATH_BORROW_DECIDER相关子函数IsNecessaryToBorrowLaneIsBlockingObstacleFarFromIntersectionIsNonmovableObstacleCheckLaneBorrow 参考 前言 在Apollo星火计划学习笔记—…

MySql014——分组的GROUP BY子句和排序ORDER BYSELECT子句顺序

前提&#xff1a;使用《MySql006——检索数据&#xff1a;基础select语句》中创建的products表 一、GROUP BY子句基础用法 SELECT vend_id, COUNT(*) AS num_prods FROMstudy.products GROUP BY vend_id;上面的SELECT语句指定了两个列&#xff0c;vend_id包含产品供应商的ID&…

Protobuf 语法详解

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

mybatisplus批量写入

1.新建MybatisPlusConfig /*** MybatisPlusConfig.*/ Configuration MapperScan("com.test.mapper") public class MybatisPlusConfig {/*** 自定义批量插入 SQL 注入器.*/Beanpublic InsertBatchSqlInjector insertBatchSqlInjector() {return new InsertBatchSqlI…

微服务(多级缓存)

多级缓存 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈Redis缓存失效时&…

【Kubernetes】Kubernetes的监控工具Promethues

Prometheus 一、Prometheus 概念1. Prometheus 概述2. Prometheus 的监控数据3. Prometheus 的特点4. Prometheus 和 zabbix 区别5. Prometheus 的生态组件5.1 Prometheus server5.2 Client Library5.3 Exporters5.4 Service Discovery5.5 Alertmanager5.6 Pushgateway5.7 Graf…

【PHP面试题81】php-fpm是什么?它和PHP有什么关系

文章目录 &#x1f680;一、前言&#xff0c;php-fpm是什么&#x1f680;二、php-fpm与PHP之间的关系&#x1f680;三、php-fpm解决的问题&#x1f50e;3.1 进程管理&#x1f50e;3.2 进程池管理&#x1f50e;3.3 性能优化&#x1f50e;3.4 并发处理 &#x1f680;四、php-fpm常…

每日一题——排序链表(递归 + 迭代)

排序链表&#xff08;递归 迭代&#xff09; 题目链接 注&#xff1a;本体的解法建立在归并排序的基础之上&#xff0c;如果对这一排序还不太了解&#xff0c;建议看看&#xff1a; &#x1f449;归并排序 &#x1f449;八大排序算法详解 &#x1f449;合并两个有序链表 既…

初学Zephyr系统,相关文档参考

https://docs.zephyrproject.org/3.0.0/reference/kconfig/index-all.html Zephyr下所有配置项Configuration Options 链接如上&#xff0c;写个博客防止自己找不到 我在调试NCS中的例程的时候会需要对prj.conf进行配置从而对Kconfig进行配置 BLE的相关API可参考https://do…

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务

[oneAPI] 基于BERT预训练模型的英文文本蕴含任务 Intel DevCloud for oneAPI 和 Intel Optimization for PyTorch基于BERT预训练模型的英文文本蕴含任务语料介绍数据集构建 模型训练 结果参考资料 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0…

Spring@Scheduled定时任务接入XXL-JOB的一种方案(基于SC Gateway)

背景 目前在职的公司&#xff0c;维护着Spring Cloud分布式微服务项目有25个。其中有10个左右微服务都写有定时任务逻辑&#xff0c;采用Spring Scheduled这种方式。 Spring Scheduled定时任务的缺点&#xff1a; 不支持集群&#xff1a;为避免重复执行&#xff0c;需引入分…

基于jeecg-boot的flowable流程加签功能实现

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 今天我…

【C++】C++ 引用详解 ① ( 变量的本质 - 引入 “ 引用 “ 概念 | 引用语法简介 | 引用做函数参数 | 复杂类型引用做函数参数 )

文章目录 一、变量的本质 - 引入 " 引用 " 概念1、变量的本质 - 内存别名2、引入 " 引用 " 概念 - 已定义变量的内存别名3、" 引用 " 的优点 二、引用语法简介1、语法说明2、代码示例 - 引用的定义和使用 三、引用做函数参数1、普通引用必须初始…

minikube安装

minikube也是需要docker环境的&#xff0c;首先看一下docker 下载docker.repo源到本地 通过repo里面查找最新的docker 开始安装docker 修改docker 下载加速地址&#xff0c; systemctl deamon-reload 下载minikube minikube start | minikube curl -LO https://storage.goog…

Mybatis(二)映射文件配置与动态SQL

Mybatis&#xff08;二&#xff09;映射文件配置 1.Mybatis映射文件配置 1.入参 1.1.parameterType(了解) CRUD标签都有一个属性parameterType&#xff0c;底层的statement通过它指定接收的参数类型。入参数据有以下几种类型&#xff1a;HashMap&#xff0c;基本数据类型&a…

会计资料基础

会计资料 1.会计要素及确认与计量 1.1 会计基础 1.2 六项会计要素小结 1.3 利润的确认条件 1.3.1 利润的定义和确认条件 1.4 会计要素及确认条件 2.六项会计要素 2.1 资产的特征及其确认条件 这部分资产可以给企业带来经济收益&#xff0c;但是如果不能带来经济利益&#xff…