[spring]处理器

news/2024/12/24 9:02:41 标签: spring, 数据库, java

    我们可以通过spring来管理我们的类,之后我们可以通过spring的容器来获取我们所需要的Bean类对象。Spring的处理器是Spring对外开发的重要扩展点,它允许我们介入到Bean的整个实例化流程中来,可以动态添加、修改BeanDefinition、动态修改Bean

     首先spring会解析配置Bean的xmlw文件,将解析结果分装成一个个BeanDifinition,存到一个BeanDifinitionMap里面。然后将该Map传入到工厂里面,然后工厂会遍历该Map得到其中的Bean对象。之后根据Bean对象的信息创建对应的类实例对象,并将这些实例对象存放到singletonObjects里面。最后,我们接收一下容器(容器本身也是一个对象),往后便可以通过这个容器来获取我们想要的实例对象。大致流程如下图,详细的可以看我的另一篇文章。

    其中我们再拆出工厂生产实例对象的过程: 

     在工厂里面,工厂首先会通过遍历拿出一个个Bean的信息,然后根据信息将其生产对应的类实例对象。生产对象后,工厂会将其打包,最后通过容器传递给调用者。

    spring里提供了两个处理器给我们进行拓展,分别是Bean工厂后处理器(BeanFactoryPostProcessor,简称BFPP)和Bean后处理器(BeanPostProcessor,简称BPP)。接下来我们介绍一下这两个处理器。

BeanFactoryPostProcessor

    Bean工厂后处理器在BeanDefinitionMap填充完毕,Bean实例化之前执行,也就是前面图里面两个绿框框中左下那个框起来的部分。

    BFPP是一个接口规范,实现BFPP的类只需要继承BeanFactoryPostProcessor接口,然后实现 void postProcessBeanFactory 方法即可。实现该接口的类只要交给spring容器管理,spring就会自动调用该实现类里的方法,以达到修改或添加BeanDefinition的目的。

    到这里,也没太多的可以讲,我们上代码示例:

配置包:

实现BFPP接口的类:

配置到Bean.xml文件:

测试类和测试结果:

    基本使用方法就如上面演示所示。postProcessBeanFactory传入的参数是spring解析完Bean配置文件之后最原始的Bean数据。我们可以通过操作这个数据来影响实例对象的创建。

    先展示用法:

     如上图,我们可以通过该方法传进来的参数beanFactory来操作BeanDefinitionMap。获得BeanDefinition对象之后我们就可以对spring解析得到的原始数据进行操作。像上图中选中的setBeanClassName就是修改该Bean的对应类的信息。方法很多,详细可以查看源码中的注释或开发者文档,这里不展开讲。

   下面我展示一下通过Bean工厂后处理器,修改原始数据,让所有原本生产User类实例对象的调用,变为生产Student类实例对象:

     然后我们看测试结果:

    而且我们来看我的Bean.xml配置文件:

     我是没有给Student类配置相关信息的。这就回到开始将到的BFPP的概念,BFPP可以在生产实例对象前对解析XML配置文件得到的原始数据进行操作。

BeanPostProcessor

    Bean后处理器跟BFPP都是一个接口,但是它执行的时间点与BFPP不一样。BFPP执行是在bean对应的类实例对象创建之前,对BeanDifinition进行操作;而BPP是对象创建之后,缓存到singletonObjects单例池之前,对实例对象初始化过程的操作,包括属性的填充、初始化方法等等,也就是前面的流程图中右上的绿框框,框起来的那一节点。

    实现方式则和BPFF大差不差,首先写一个类,实现BeanPostProcessor接口,实现其中的 postProcessBeforeInitialization和postProcessAfterInitialization 两个方法,后续简称before方法和after方法。

    在Bean里面我们可以设置初始化方法和销毁方法,而BPP的作用与初始化方法的作用很类似。这三者之间的执行顺序是:before>>inti(初始化方法)>>after

    当然,这两种的作用不可能就只是初始化,BPP主要用于实现动态代理,实现对类的增强,增强可以理解为对一个类实例对象拓展其功能。这么说比较抽象,我打个比方。你去汤面馆吃面,点了个牛肉面。按店家正常做出来的牛肉面,你觉得不够鲜不够香,于是你端着面到调料台前加了一勺香菜。

    店家把面做出来就是根据Bean的信息生产出实例对象,你加香菜就是使用BPP对实例对象进行增强。动态代理我会开篇新文章讲。


http://www.niftyadmin.cn/n/5797599.html

相关文章

img向后端获取图片时怎么解决需携带token的问题

1、 问题: 我在vue3的一个项目,需要使用img标签获取后端的图片,但是需要在请求头添加token。尝试发现这种请求不经过axios的拦截请求,且不能以参数的方式携带token(不安全) 2、解决方法: 自定义…

青少年编程与数学 02-004 Go语言Web编程 18课题、日志记录

青少年编程与数学 02-004 Go语言Web编程 18课题、日志记录 一、日志记录(一)目的(二)内容类型(三)日志记录的格式 二、Go Web 日志记录1. 使用标准库 log 包2. 使用 logrus3. 在 Gin 框架中集成 logrus4. 使…

概率论 期末 笔记

第一章 随机事件及其概率 利用“四大公式”求事件概率 习题 推导 全概率公式与贝叶斯公式 伯努利概型求概率 一维随机变量及其分布

使用 pyreqs 快速创建 requirements.txt PyCharm 中 UnicodeDecodeError 问题

目录 什么是 requirements.txt?pyreqs 包分析与解决:应对 JetBrains IDE 中 pipreqs 的 UnicodeDecodeError 问题参考链接 什么是 requirements.txt? 在现代软件开发中,requirements.txt 是用于定义和管理项目依赖的核心文件,主要功能在于…

ADB在浏览器中的革命:ya-webadb项目解析及新手指南

ADB在浏览器中的革命:ya-webadb项目解析及新手指南 ya-webadb ADB in your browser [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/ya/ya-webadb ya-webadb是一个创新的开源项目,它将Android调试桥(ADB)的功能带入了基于Chromium的浏览器…

vue3和element-plus笔记

对子组件直接使用v-model 子组件内定义如下 const props defineProps({modelValue: {type: String,required: true} }) const emits defineEmits(["update:modelValue"]) 父组件定义如下 <script setup> const deleteId ref(null) </script> <…

Java多线程第二篇-线程的常用方法和线程安全

文章目录 一.线程的常用方法1.线程终止1.1通过成员对线程进行终止1.2通过Thread本地方法终止 2.线程的等待join2.1不增加参数2.2增加参数2.3线程的休眠时间 二.线程的其他状态三.线程安全3.1多线程执行3.2线程加锁3.2.1死锁3.2.2哲学家进餐3.2.3并行算法3.2.4死锁的达成条件 3.…

数据库的三范式是什么?

第一范式&#xff08;1NF&#xff09; 每列的原子性&#xff0c;表中的每一个字段都是不可分割的&#xff0c;同一列中不能有多个值。第一范式是对关系模式的基本要求&#xff0c;不满足第一范式的数据库不是关系型数据库。 ・不满足第一范式的示例&#xff1a; 学生编号 学生…