【Spring】——11、了解BeanPostProcessor后置处理器

news2025/7/3 7:11:24

在这里插入图片描述

📫作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等

本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

文章目录

  • 1、介绍
  • 2、实例
    • 2.1、创建TestBeanPostProcessor类
    • 2.2、创建普通Bean
    • 2.3、配置类
    • 2.4、测试类
    • 2.5、运行结果
  • 3、作用

1、介绍

BeanPostProcessor在Spring中是一个很强大的后置处理器接口,常用于注解处理,比如我们常用的@Value本质就是用这个后置处理器处理,那么BeanPostProcessor长的是什么样子的呢?代码如下。

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

/**
 * Factory hook that allows for custom modification of new bean instances —
 * for example, checking for marker interfaces or wrapping beans with proxies.
 *
 * <p>Typically, post-processors that populate beans via marker interfaces
 * or the like will implement {@link #postProcessBeforeInitialization},
 * while post-processors that wrap beans with proxies will normally
 * implement {@link #postProcessAfterInitialization}.
 *
 * <h3>Registration</h3>
 * <p>An {@code ApplicationContext} can autodetect {@code BeanPostProcessor} beans
 * in its bean definitions and apply those post-processors to any beans subsequently
 * created. A plain {@code BeanFactory} allows for programmatic registration of
 * post-processors, applying them to all beans created through the bean factory.
 *
 * <h3>Ordering</h3>
 * <p>{@code BeanPostProcessor} beans that are autodetected in an
 * {@code ApplicationContext} will be ordered according to
 * {@link org.springframework.core.PriorityOrdered} and
 * {@link org.springframework.core.Ordered} semantics. In contrast,
 * {@code BeanPostProcessor} beans that are registered programmatically with a
 * {@code BeanFactory} will be applied in the order of registration; any ordering
 * semantics expressed through implementing the
 * {@code PriorityOrdered} or {@code Ordered} interface will be ignored for
 * programmatically registered post-processors. Furthermore, the
 * {@link org.springframework.core.annotation.Order @Order} annotation is not
 * taken into account for {@code BeanPostProcessor} beans.
 *
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 10.10.2003
 * @see InstantiationAwareBeanPostProcessor
 * @see DestructionAwareBeanPostProcessor
 * @see ConfigurableBeanFactory#addBeanPostProcessor
 * @see BeanFactoryPostProcessor
 */
public interface BeanPostProcessor {

	/**
	 * Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 * Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean
	 * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
	 * or a custom init-method). The bean will already be populated with property values.
	 * The returned bean instance may be a wrapper around the original.
	 * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
	 * instance and the objects created by the FactoryBean (as of Spring 2.0). The
	 * post-processor can decide whether to apply to either the FactoryBean or created
	 * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
	 * <p>This callback will also be invoked after a short-circuiting triggered by a
	 * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
	 * in contrast to all other {@code BeanPostProcessor} callbacks.
	 * <p>The default implementation returns the given {@code bean} as-is.
	 * @param bean the new bean instance
	 * @param beanName the name of the bean
	 * @return the bean instance to use, either the original or a wrapped one;
	 * if {@code null}, no subsequent BeanPostProcessors will be invoked
	 * @throws org.springframework.beans.BeansException in case of errors
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
	 * @see org.springframework.beans.factory.FactoryBean
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

  • 我们可以发现其主要有两个方法,见名思意可知一个是初始化之前,初始化之后。
  • postProcessBeforeInitialization方法会在bean实例化和属性设置之后,自定义初始化方法之前被调用,而postProcessAfterInitialization方法会在自定义初始化方法之后被调用。当容器中存在多个BeanPostProcessor的实现类时,会按照它们在容器中注册的顺序执行。对于自定义的BeanPostProcessor实现类,还可以让其实现Ordered接口自定义排序。
  • 我们可以通过BeanPostProcessor处理一些自己的逻辑。

2、实例

2.1、创建TestBeanPostProcessor类

  • 首先我们写一个TestBeanPostProcessor类去实现BeanPostProcessor接口,如果需要需要指定执行顺序,自行实现Ordered接口(可选),代码如下
package com.zhz.beanpostprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 后置处理器,在初始化前后进行处理工作
 *
 * @author zhouhengzhe
 * @date 2022/11/24
 */
@Component // 将后置处理器加入到容器中,这样的话,Spring就能让它工作了
public class TestBeanPostProcessor implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization=>"+beanName+":=>"+bean);
        return bean;
    }

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

    
    @Override
    public int getOrder() {
        return 0;
    }
}

2.2、创建普通Bean

我们创建一个普通bean去实现InitializingBean, DisposableBean,好验证一下跟BeanPostProcessor之间的执行关系。

package com.zhz.bean;

import lombok.Data;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

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

/**
 * @author zhouhengzhe
 * @date 2022/11/23
 */
@Data
public class PostPerson implements InitializingBean, DisposableBean {

    // 在对象创建完成并且属性赋值完成之后调用
    @PostConstruct
    public void init() {
        System.out.println("postConstruct..init.");
    }

    // 在容器销毁(移除)对象之前调用
    @PreDestroy
    public void preDestroy() {
        System.out.println("PreDestroy...preDestroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("PostPerson afterPropertiesSet...");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("PostPerson destroy...");
    }
}

2.3、配置类

package com.zhz.config;

import com.zhz.bean.PostPerson;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 生命周期相关配置
 * @author zhouhengzhe
 * @date 2022/11/21
 */
@Configuration
@ComponentScan("com.zhz.beanpostprocessor")
public class MainConfigByLifeCycle {

    @Bean
    public PostPerson personPerson() {
        return new PostPerson();
    }

}

2.4、测试类

  @Test
    public void test4ByPostConstruct(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigByLifeCycle.class);
        applicationContext.close();
    }

2.5、运行结果

在这里插入图片描述

由上面的运行结果可知,执行顺序为:

  • postProcessBeforeInitialization=>@postConstruct=>InitializingBean(afterPropertiesSet)=>postProcessAfterInitialization=>@PreDestroy=>DisposableBean(destroy)

3、作用

  • 后置处理器可用于bean对象初始化前后进行逻辑增强。Spring提供了BeanPostProcessor接口的很多实现类,例如AutowiredAnnotationBeanPostProcessor用于@Autowired注解的实现,AnnotationAwareAspectJAutoProxyCreator用于Spring AOP的动态代理等等。

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

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

相关文章

Packet Tracer - 综合技能练习(通过调整 OSPF 计时器来修改 OSPFv2 配置)

地址分配表 设备 接口 IP 地址 子网掩码 RA G0/0 192.168.1.1 255.255.255.0 RB G0/0 192.168.1.2 255.255.255.0 RC G0/0 192.168.1.3 255.255.255.0 S0/0/0 209.165.200.225 255.255.255.252 拓扑图 场景 在此综合技能练习中&#xff0c;您的重点是 OSPF…

【滤波跟踪】不变扩展卡尔曼滤波器对装有惯性导航系统和全球定位系统IMU+GPS进行滤波跟踪【含Matlab源码 2232期】

⛄一、简介 针对室内定位中的非视距&#xff08;Non-Line-of-Sight,NLOS&#xff09;现象,提出一个新型算法进行识别,同时有效缓解其影响.主要通过超宽带&#xff08;Ultra-Wideband,UWB&#xff09;定位系统与惯性导航系统&#xff08;Inertial Navigation System,INS&#x…

车辆大全和车牌识别系统毕业设计,车牌识别系统设计与实现,车牌AI识别系统论文毕设作品参考

功能清单 【后台管理员功能】 系统设置&#xff1a;设置网站简介、关于我们、联系我们、加入我们、法律声明 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&a…

发布MagicOS 7.0, 荣耀如何打造“松弛感”的操作系统?

最近&#xff0c;“松弛感”一词特别流行。有博主教网友如何打造松弛感美女&#xff0c;因为这种毫不费力、天然去雕饰的美&#xff0c;更有吸引力&#xff1b;职场松弛感&#xff0c;能够平衡工作和生活&#xff0c;更被同事们喜欢&#xff1b;生活也需要多一些松弛感&#xf…

C. Doremy‘s City Construction(思维)

Problem - C - Codeforces Doremy的新城市正在建设中! 这个城市可以被看作是一个有n个顶点的简单无向图。第i个顶点的高度为ai。现在&#xff0c;多雷米正在决定哪些顶点对应该用边连接。 由于经济原因&#xff0c;图中不应该有自循环或多条边。 由于安全原因&#xff0c;不应…

mybatis基础01

一、安装mybatis 要使用 MyBatis&#xff0c; 只需将 mybatis-x.x.x.jar 文件置于类路径&#xff08;classpath&#xff09;中即可。 如果使用 Maven 来构建项目&#xff0c;则需将下面的依赖代码置于 pom.xml 文件中&#xff1a; <dependency><groupId>org.mybat…

贺利坚汇编语言课程笔记 绪论

贺利坚汇编语言课程笔记 绪论 又是女娲补天式地从零开始两周零基础冲击六十分… 文章目录贺利坚汇编语言课程笔记 绪论一.Why should we learn Assembly language&#xff1f;二.从机器语言到汇编语言三.计算机组成指令和数据的表示计算机中的存储单元计算机中的总线x86CPU性能…

Java日期时间的前世今生

&#x1f649; 作者简介&#xff1a; 全栈领域新星创作者 &#xff1b;天天被业务折腾得死去活来的同时依然保有对各项技术热忱的追求&#xff0c;把分享变成一种习惯&#xff0c;再小的帆也能远航。 &#x1f3e1; 个人主页&#xff1a;xiezhr的个人主页 前言 日常开发中&…

gitpod.io,云端开发调试工具。

gitpod&#xff0c;一款在线开发调试工具&#xff0c;使用它你可以在网页上直接开发软件项目了。 比如你的项目仓库在github上&#xff0c;你可以直接在网址的前面添加gitpod.io/#&#xff0c;然后回车就能在网页上使用vscode打开这个项目了。 打开的效果&#xff1a; 可以安装…

ZZULIOJ 2066: 带分数

ZZULIOJ 2066: 带分数 题意&#xff1a; 给定一个数NNN&#xff0c;问有多少组a,b,ca,b,ca,b,c满足abcNa\dfrac bcNacb​N&#xff0c;且a,b,ca,b,ca,b,c三个数不重不漏地涵盖1−91-91−9这999个数字&#xff0c;输出总组数 解题思路&#xff1a; 暴力枚举出999个数的全排列…

sql数据库入门(1)

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f; c语言初阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>: 本篇记录一下牛牛在学校学习的sql serve数据库知识,内…

学了PS了还用学习AI吗,有什么区别

AdobeIllustrator和AdobePhotoshop它是目前市场上设计师使用最广泛的两种软件。很多刚接触的同学会发现&#xff0c;两者都可以达到一些效果&#xff0c;导致一种错觉&#xff0c;认为任何人都可以使用&#xff0c;所以他们可以随意使用。 虽然在PS和Ai它确实可以用来做类似的…

顶刊示例-经济研究数据-全国、省、市-城市人均收入、农村人均收入面板数据

&#xff08;1&#xff09;全国城乡居民人均收入 1、数据来源&#xff1a;中国统计年鉴 2、时间跨度&#xff1a;1978-2020 3、区域范围&#xff1a;国家 4、指标说明&#xff1a; 包含如下指标&#xff1a; 全国居民人均可支配收入 城镇居民人均可支配收入 农村居民人均…

深入浅出解析——MYSQL|触发器

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

AtCoder Beginner Contest 279 F BOX 并查集 (大意失荆州

前言 赛时一直RE&#xff0c;思路很清晰&#xff0c;不知道RE哪里。。qwq 赛后开断点发现&#xff0c;map的大小不变&#xff0c; 最后发现是一个if条件写错了&#xff0c;寄。 不知道为什么会想起 银河英雄传说 题意&#xff1a; 初始n个盒子&#xff0c;盒子iii放着编号为i…

2023年天津财经大学珠江学院专升本退役士兵免试职业技能考查大纲

天津财经大学珠江学院2023年高职升本科职业技能综合考查考试大纲 &#xff08;仅适用于符合条件的退役士兵考生&#xff09;《管理学原理》 一、本大纲系天津财经大学珠江学院2023年高职升本科《管理学原理》职业技能综合考查考试大纲&#xff0c;仅适用于符合条件的退役士兵考…

面试官:synchronized与Lock有什么区别?

作为一名程序员&#xff0c;在求职面试时&#xff0c;不知道你在求职面试时常会遇到关于线程的问题。张工是一名java程序员&#xff0c;3年多工作经验&#xff0c;有次到一家互联网公司面试软件开发工程师岗位&#xff0c;面试官就问了他这样一个问题。synchronized与Lock有什么…

Android APP深度优化—内存映射机制(mmap)

mmap原理 open一个文件&#xff0c;然后调用mmap系统调用&#xff0c;将文件的内容的全部或一部分直接映射到进程虚拟空间中文件存储映射部分&#xff1b;完成映射关系后&#xff0c;mmap返回值是一个指针&#xff0c;进程可以通过采用指针方式读写操作这一段内存&#xff1b;…

vue3 antd项目实战——使用filter实现简单的table表格搜索功能

零基础filter实现最简单的table表格知识调用核心干货下期预告关键字模糊查找&#xff08;纯前端&#xff09;关键字模糊查找&#xff08;前后交互&#xff09;知识调用 功能实现可能要用到的知识&#xff1a;vue3ant design vuets实战【ant-design-vue组件库引入】vue3项目实战…

MyBatis-Plus删除操作知识点总结

系列文章目录 Mybatis-Plus知识点[MyBatisMyBatis-Plus的基础运用]_心态还需努力呀的博客-CSDN博客 Mybatis-PlusSpringBoot结合运用_心态还需努力呀的博客-CSDN博客MyBaits-Plus中TableField和TableId用法_心态还需努力呀的博客-CSDN博客MyBatis-Plus中的更新操作&#xf…