Spring后置处理器(PostProcessor)

news2024/11/26 16:54:43

文章目录

      • 引言
      • BeanFactoryPostProcessor
        • 常见用法
        • 创建自定义后置处理器
        • 注册后置处理器
        • 执行后置处理器
      • BeanPostProcessor
        • 常见用法
        • 创建自定义后置处理器
        • 注册后置处理器
        • 执行后置处理器
      • 实际需求
        • 验证配置文件的正确性
          • 检验逻辑

引言

在Spring框架中,后置处理器为我们提供了一种机制,可以在Spring容器实例化、配置Bean之后,以及在Bean初始化方法(如使用@PostConstruct注解的方法)执行前后,插入自定义的逻辑。这种机制在处理跨多个Bean的通用逻辑时特别有用,如属性修改、依赖注入增强、代理模式应用等。

BeanFactoryPostProcessor

BeanFactoryPostProcessor 是 Spring 框架中另一个重要的后置处理器接口,与 BeanPostProcessor 不同,BeanFactoryPostProcessor 是在 Spring 容器加载了所有的 Bean 定义之后,但在任何 Bean 实例化之前调用的。这使得 BeanFactoryPostProcessor 能够在容器上下文中修改 Bean 定义或添加额外的属性。

常见用法
  1. 修改 Bean 定义:你可以使用 BeanFactoryPostProcessor 来修改容器中 Bean 的定义,比如改变 Bean 的作用域、添加或修改 Bean 的属性等。
  2. 添加自定义的 Bean:在容器启动过程中动态地添加额外的 Bean 定义。
  3. 环境相关的配置:根据应用运行的环境(如开发、测试、生产)来动态调整配置。
  4. 注册自定义的 BeanPostProcessor:虽然 BeanPostProcessor 可以通过 @Component 或 XML 配置来注册,但有时你可能想要在运行时根据条件动态地注册它们。
创建自定义后置处理器
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("执行了后置处理器");
        // 自定义逻辑
    }
}
注册后置处理器

创建完自定义后置处理器后,我们需要在Spring容器中注册它。这可以通过在配置类上使用@Bean注解或者在XML配置文件中声明来实现。

如果你使用Java配置,可以这样做:

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
public class AppConfig {  
      
    @Bean  
    public CustomBeanFactoryPostProcessor customBeanPostProcessor() {  
        return new CustomBeanFactoryPostProcessor();  
    }  
}

如果你使用XML配置,可以这样做:

<beans xmlns="http://www.springframework.org/schema/beans">  
    <!-- 其他Bean配置 -->  
    <bean class="com.example.CustomBeanFactoryPostProcessor"/>  
</beans>
执行后置处理器

当你启动Spring应用时,Spring容器会自动检测并调用所有注册的后置处理器。

你不需要显式地调用后置处理器的方法;这一切都是自动发生的。只需确保你的后置处理器被正确地注册到了Spring容器中。

执行结果:

这里可以看到是执行了我们的后置处理器的

在这里插入图片描述


BeanPostProcessor

BeanPostProcessor 是 Spring 框架中的一个重要接口,它允许在 Spring 容器创建 Bean 对象并执行初始化方法(如 InitializingBean.afterPropertiesSet 或自定义的 init 方法)的前后进行额外的处理。这个接口定义了两个主要的回调方法:postProcessBeforeInitializationpostProcessAfterInitialization

常见用法
  • postProcessBeforeInitialization:在 Bean 实例化、属性注入后,但在执行任何初始化方法(如 afterPropertiesSet)之前调用。这个方法允许我们对 Bean 进行一些预处理,比如检查标记接口、修改 Bean 的属性或者用代理包装 Bean。
  • postProcessAfterInitialization:在 Bean 实例化、属性注入以及初始化方法执行完成后调用。这个方法允许我们对已经初始化完成的 Bean 进行后处理,比如进行一些资源的清理、性能的监测等。
创建自定义后置处理器
public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化之前执行的逻辑
        System.out.println("Before Initialization : " + beanName);
        return bean;  // 可以返回原Bean,或者返回一个包装后的Bean
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在Bean初始化之后执行的逻辑
        System.out.println("After Initialization : " + beanName);
        return bean;  // 可以返回原Bean,或者执行一些额外操作后的Bean
    }
}
注册后置处理器

注册后置处理器的方式和前面的一样,要么通过xml文件的方式进行注入,或者使用bean对象的方式进行注入。

执行后置处理器

这里将我们的上面的后置处理器和这个处理器都注入进去,然后我们可以看到执行的顺序就是先执行**beanFactoryPostProcessor**后置处理器,后面才执行bean对象的后置处理器。

在这里插入图片描述

实际需求

验证配置文件的正确性

自己自定义了一个jar包依赖,那么其他人进行导入的时候,配置可能是会出错的。这里我们可以使用**beanFactoryPostProcessor**进行检查,检查提取占位符以后的文件格式是否有问题,有问题则直接报错。

检验逻辑
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        BeanDefinition beanDefinition = configurableListableBeanFactory.getBeanDefinition("A");
        PropertyValue name = beanDefinition.getPropertyValues().getPropertyValue("name");
        System.out.println("name.getValue().toString() = " + name.getValue().toString());
        if (name.getOriginalPropertyValue() != null) { // 检验提取的占位符的格式是否正确
            throw new BeanCreationException(" name error !");
        }
    }
}

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

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

相关文章

主流公链 - Monero

Monero: 加密货币的隐私标杆 1. 简介 Monero&#xff08;XMR&#xff09;&#xff0c;世界语中货币的意思&#xff0c;是一种去中心化的加密货币&#xff0c;旨在提供隐私和匿名性。与比特币等公开区块链不同&#xff0c;Monero专注于隐私保护&#xff0c;使用户的交易记录和余…

24/03/28总结

抽象类&#xff1a; 将共性的方法抽取到父类之后。由于每一个子类执行的内容是不一样&#xff0c;所以&#xff0c;在父类中不能确定具体的方法体。该方法就可以定义为抽象方法。 而为什么不直接在子类中定义方法&#xff1a;项目的完成不是一个人&#xff0c;如果有时忘记写方…

JavaEE 初阶篇-深入了解多线程等待与多线程状态

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 线程等待 1.1 线程等待 - join() 方法 1.1.1 main 线程中等待多个线程 1.1.2 main 线程等待 t2 线程且t2 线程等待 t1 线程 1.1.3 其他线程阻塞等待 main 线程 1.…

解决 linux 服务器 java 命令不生效问题

在Linux系统中&#xff0c;当你安装Java并设置了JAVA_HOME环境变量后&#xff0c;你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件&#xff0c;它包含了系统的全局环境变量设置。 但是需要注意的是&#xff0c;source /e…

防水游泳耳机有哪些?四款口碑销量双丰收的尖货揭晓

游泳时享受音乐的快乐已成为许多人的追求。防水游泳耳机&#xff0c;作为这一追求的重要工具&#xff0c;不仅让我们在水中畅游时能够感受到音乐的魅力&#xff0c;同时也提升了游泳的乐趣。然而&#xff0c;面对市场上琳琅满目的产品&#xff0c;如何选择一款既防水又音质出色…

Java基础-子类与继承

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、继承的概念 二、Java 方法重写 三、Object类 方法 四、final关键字 final 变量 五、Java 多态 …

Oracle 19C RAC集群补丁升级

文章目录 一、补丁包概述二、OPatch检查和更新Grid用户更新OPatchOracle用户更新OPatch 三、验证Oracle Inventory的有效性四、运行 OPatch 冲突检查五、运行opatch命令检查GI HOME下是否有足够的空间六、补丁冲突检测与解决&#xff08;修补程序&#xff09;七、使用root用户应…

scGRN:人与鼠的GRN平台

基因调控网络GRN是包含转录因子TFs与其下游靶基因之间的调控相互作用的可解释图模型。了解GRN的拓扑结构和动力学是解释疾病病因机制和将相应发现转化为新疗法的基础。单细胞多组学技术的最新进展促使从单细胞转录组学和表观基因组学数据中以前所未有的分辨率推断GRN。在这里&a…

mysql5.7 源码分析--初始化

集中在sql\mysqld.cc文件的mysqld_main函数中&#xff08;&#xff09;&#xff1a; 主程序入口 在sql\main.cc文件中&#xff1a; int main(int argc, char **argv) {return mysqld_main(arg, argv); } 一、mysql为了跨平台&#xff0c;对win32系统做了单独的初始化&#x…

GitLab更新失败(Ubuntu)

在Ubuntu下使用apt更新gitlab报错如下&#xff1a; An error occurred during the signature verification.The repository is not updated and the previous index files will be used.GPG error: ... Failed to fetch https://packages.gitlab.com/gitlab/gitlab-ee/ubuntu/d…

双指针算法_和为 s 的两个数_C++

题目&#xff1a; 输入一个递增排序的数组&#xff0c;和一个数字s&#xff0c;在数组中查找两个数&#xff0c;使得它们的和正好是数字s&#xff0c;如果有多对数字的和等于s&#xff0c;只需要任意输入一对即可 算法原理&#xff1a; 利用单调性&#xff01;使用双指针算法&…

STL —— vector(1)

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C专栏 本篇文章主要讲解vector使用的相关内容 1. vector简介 vector 是 C 标准库中的一个容器类模板&#xff0c;它提供了动态数组的功能&#xff0c;可以方便地管理和操作元素的集合。下面是关于 vector 的一些基本信…

基于unbantu的nginx的配置

目录 前言: 1.安装nginx并进行测试 1.1使用nginx -v 命令查看版本 1.2开启服务 查看端口 1.3测试 2.nginx的静态资源访问配置 2.1创建静态资源存放的目录 2.2写入目录中测试文件对应的内容 2.3修改配置文件 2.4 测试 3.虚拟主机配置 3.1创建目录 3.2写入测试…

[flask]http请求//获取请求体数据

import jsonfrom flask import Flask, requestapp Flask(__name__)app.route("/form1", methods["post"]) def form1():"""获取客户端请求的请求体[表单]:return:""""""获取表单数据请求url&#xff1a;&qu…

【mysql】centos7安装mysql8

目录 1. 下载安装包2. 解压tar包3. 安装4. 查看安装完成后的安装包5. 初始化mysql6. MySQL设置 1. 下载安装包 1.官网地址2.mysql-8.0.35-1.el7.x86_64.rpm-bundle.tar3.放到服务器的目录&#xff08;这里是/opt/mysql&#xff09; 2. 解压tar包 1.tar -xvf 可以解压tar.xz后…

批量下载网页文章软件大全

在信息爆炸的时代&#xff0c;网络上充斥着海量的文章和内容&#xff0c;有时我们希望能够批量下载网页上的文章&#xff0c;以便离线阅读或进行进一步处理。为了满足这一需求&#xff0c;出现了许多网页文章批量下载工具&#xff0c;它们能够帮助用户快速、方便地获取网页上的…

【IC前端虚拟项目】write_path子模块DS与RTL编码

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 read_path的代码完成之后,就可以开始整个项目里复杂度最高、bug最多、时序收敛最为困难的模块——write_path的开发了!我自己写过两次这个虚拟项目,每次都是在这里耗时最久,所以大家也可以挑战一下自…

使用AOP实现打印日志

首先创建annotation.SystemLog类&#xff1a; package com.gjh.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.METHOD…

蓝桥杯-卡片换位

solution 有一个测试点没有空格&#xff0c;要特别处理&#xff0c;否则会有一个测试点运行错误&#xff01; 还有输入数据的规模在变&#xff0c;小心顺手敲错了边界条件 #include<iostream> #include<string> #include<queue> #include<map> #incl…

JS new Array.fill(new Array()) 创建二维数组 fill方法的坑

我们通常会通过如下方式来创建一个二维数据&#xff1a; const arr new Array(5).fill(new Array(2).fill(0))我们如果想要修改其中一个元素的值 arr[0][0] 1输出&#xff1a;   我们只想给arr[0][0]赋值&#xff0c;但是每一行数组为0的下标元素的值全部改变了&#xf…