详解Spring中BeanPostProcessor在Spring工厂和Aop发挥的作用

news2025/5/26 8:56:31

😉😉 学习交流群:

✅✅1:这是孙哥suns给大家的福利!

✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料

🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取!

🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

💞💞5:以上内容,进群免费领取呦~ 💞💞💞💞

一:BeanPostProcessor分析

1:BeanPostProcessor对于Spring工厂作用

        这个事后置处理Bean,这个东西的全称叫做BeanPostProcessor,最主要的作用是对Spring创建的对象进行再加工,这个是Spring工厂中的一个非常有用的高级特性,在Spring底层很多高级的封装的时候都有这个技术的影子,讲了Aop底层的实现的时候,会发现这个技术的价值是非常高的,Spring的Aop底层实现很大的一部分是这个技术进行支撑。

        BeanPostProcessor是对Spring的bean工厂进行在加工,Spring工厂创建对象的过程是:Spring获取Spring的核心配置文件之后对spring的核心配置文件进行解析,获取到响应的bean标签会后,通过反射技术调用该类的构造方法,创建该类的实例,第二件事是spring对这个类中的成员变量按照配置进行注入,注入完成之后,调用这个类的初始化方法,对这个类进行一个初始化,这个初始化方法是我们自己定义的,经过这样的一个过程,这个对象就创建并初始化好了,现在就可以通过getBean通过id进行获取这个对象,而这个后置处理bean,是在工厂创建完成这个对象之后,对这个对象进行再次加工,这就是这门技术的意义,那么她是怎么实现对这个工厂创建出来的对象进行再次加工的呢?BeanPostProcessor是一个接口,我们需要把这个对象加工的内容写到接口实现类对应的方法中即可。

        在这个接口当中呢有两两个方法,第一个方法是postProcessBeforeInitialization,另外的方法叫after,,这样的接口,当Bean实现了这个接口之后,spring在创建这个对象的过程中,在spring完成调用构造方法创建实例,并依据配置进行注入之后,spring就会调用这个类的postProcessBeforeIntitialzation方法进行一个初始化操作,是通过这个方法中的第一个Object类型bean参数进行传递的,另外一个参数,是这个对象在spring中的id值。在这个方法中通过这两个参数就获取到了这个参数,就可以在方法中对这个实例进行加工了。还要把这个加工好的对象交还给spring,通过参数把这个对象进行处理,交还给spring之后,执行我们配置好的初始化方法,然后将这个对象交给after这个方法,通过这个方法进行一次在加工,加工完毕之后,将这个参数传递个返回给spring。最后在客户处可以通过getBean方法进行获取。


        这就是bean引入了BeanPostProcessor这个技术之后的全部的过程分析。后置处理bean的运行原理分析。
        对于使用者,我们的作用就是让我们的bean实现这样的接口和接口中的方法,返回的值是Object


        具体过程:创建实例-注入-before方法-初始化方法-After方法
        有了这两个方法之后呢,实际的过程中,我们我们极少做初始化操作,所以,我们区分这个之前之后,这两个操作就合二为一的,

        实际上spring的初始操作使用的很少,所以,这个所谓的前后,也就没有什么前后之分了,两个挨着呢,实现其中的一个方法即可,也就是将代码写入到一个方法中就可以了。选谁,选After就可以了。但是啥也不干你也得有一个return  bean得到操作。需要注意的事before这个操作,我们必须return bean对象,这张图使我们必须要理解的内容。

package com.spring;

import com.spring.postBeanProcessor.Catagory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:17
 * @Description:
 */
public class TestPostBeanProcessor {
    @Test
    public void test1(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext1.xml");
        //-----------------------before-----------------------
        //PostBeanProcessorTest{id=10, name='xioajianren'}
        //-----------------------before-----------------------
        //------------------------init-----------------------
        //PostBeanProcessorTest{id=11, name='xiaojianren1'}
        //--------------------------init---------------------
        //---------------------------after-------------------------------
        //PostBeanProcessorTest{id=12, name='xiaojianren2'}
        //---------------------------after-------------------------------
    }
}


package com.spring.postBeanProcessor;

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:38
 * @Description:
 */
public class Catagory {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "PostBeanProcessorTest{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public void init(){
        System.out.println("------------------------init-----------------------");
        System.out.println(this.toString());
        System.out.println("--------------------------init---------------------");
    }

}

package com.spring.postBeanProcessor;

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

/**
 * @Auther: DaShu
 * @Date: 2021/6/24 21:04
 * @Description:
 */
public class PostBeanProcessorTest implements BeanPostProcessor {


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof com.spring.postBeanProcessor.Catagory){
            System.out.println("-----------------------before-----------------------");
            System.out.println(bean.toString());
            ((com.spring.postBeanProcessor.Catagory)bean).setId(11);
            ((com.spring.postBeanProcessor.Catagory)bean).setName("xiaojianren1");
            System.out.println("-----------------------before-----------------------");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("---------------------------after-------------------------------");
        ((com.spring.postBeanProcessor.Catagory)bean).setId(12);
        ((com.spring.postBeanProcessor.Catagory)bean).setName("xiaojianren2");
        System.out.println(bean.toString());
        System.out.println("---------------------------after-------------------------------");
        return bean;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id = "catagory" class = "com.spring.postBeanProcessor.Catagory" init-method="init">
        <property name="id" value="10"/>
        <property name="name" value="xioajianren"/>
    </bean>
    <bean id = "postBeanProcessorTest" class = "com.spring.postBeanProcessor.PostBeanProcessorTest" />

</beans>

2:BeanPostProcessor对于AOP作用

        Spring工厂如何加工创建代理对象

        为什么通过原始对象id获取的是代理对象的id值呢?这是aop的核心原理的第二个问题。        

        Spring的工厂是如何加工和创建这个对象呢?
        在spring创建一个对象的时候,spring的工厂可以通过BeanPostProcessor这个工厂来进一步加工这个对象,我们的当时写的案例非常的简单,创建好对象之后,spring工厂调用,在后置BeanPostProcessor当中对这个bean进行赋值,然后将处理后的bean进行返回,当动态代理结合上beanpostprocessor之后,就可以实现这个通过原始的id返回对应的代理对象,其原理呢就是将这个加工代理对象的方法写入到这个后置处理bean中BeanPostProcessor当中的PostProcessorAfterInization这个方法中,然后将代理对象的地址进行返回即可。
我们知道我们很少做这个初始化操作,所以,这个前置处理和后置处理的位置是挨着的,他们的作用是完全一样的,这样的before我们就不用了,直接将bean对象进行返回,交还给spring即可,然后呢,这个所有加工的代理都写在了后置处理的这个方法中,调用的事Proxy.newProxyInstance()这个方法,这里的实现前边都讲过了,然后将创建好的代理对象交还给spring工厂,这样spring工厂就可以通过id获取的事代理对象,这就是通过原始对象的id值获取的事代理对象的加工。

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

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

相关文章

【论文阅读】ICRA: An Intelligent Clustering Routing Approach for UAV Ad Hoc Networks

文章目录 论文基本信息摘要1.引言2.相关工作3.PROPOSED SCHEME4.实验和讨论5.总结补充 论文基本信息 《ICRA: An Intelligent Clustering Routing Approach for UAV Ad Hoc Networks》 《ICRA:无人机自组织网络的智能聚类路由方法》 Published in: IEEE Transactions on Inte…

FISCO-BCOS 在ARM系统架构搭建节点(国密版)

问题&#xff1a; 使用 fisco-bcos v2.9.1 搭建一个节点&#xff0c;批量上链1000条数据&#xff0c;在上链200条-400条数据之间节点会出现异常&#xff0c;导致后面数据不能上链。 系统环境 操作系统&#xff1a;统信 查看系统构架 ld -version rootuos-PC:/# ld -version …

RK3568平台开发系列讲解(Linux系统篇)netlink 监听广播信息

** 🚀返回专栏总目录 文章目录 一、什么是netlink 机制二、netlink 的使用2.1、创建 socket2.2、绑定套接字2.3、接收数据沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍如何通过 netlink 监听广播信息。 一、什么是netlink 机制 Netlink 是 Linux 内核中…

【C/C++笔试练习】公有派生、构造函数内不执行多态、抽象类和纯虚函数、多态中的缺省值、虚函数的描述、纯虚函数的声明、查找输入整数二进制中1的个数、手套

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;公有派生&#xff08;2&#xff09;构造函数内不执行多态&#xff08;3&#xff09;抽象类和纯虚函数&#xff08;4&#xff09;多态中的缺省值&#xff08;5&#xff09;程序分析&#xff08;6&#xff09;重载和隐藏&a…

使用gcloud SDK 管理和部署 Cloud run service

查看cloud run 上的service 列表&#xff1a; gcloud run services list > gcloud run services listSERVICE REGION URL LAST DEPLOYED BY LAST DEPL…

【Go语言反射reflect】

Go语言反射reflect 一、引入 先看官方Doc中Rob Pike给出的关于反射的定义&#xff1a; Reflection in computing is the ability of a program to examine its own structure, particularly through types; it’s a form of metaprogramming. It’s also a great source of …

Android BT HCI分析简介

对于蓝牙开发者来说&#xff0c;通过HCI log可以帮助我们更好地分析问题&#xff0c;理解蓝牙协议&#xff0c;就好像网络开发一定要会使用Wireshark分析网络协议一样。 本篇主要介绍HCI log的作用、如何抓取一份HCI log&#xff0c;并结合一个实际的例子来说明如何分析HCI log…

004、简单页面-基础组件

之——基础组件 目录 之——基础组件 杂谈 正文 1.Image 1.0 数据源 1.1 缩放 1.2 大小 1.3 网络图片 2.Text 2.0 数据源 2.1 大小 2.2 粗细 2.3 颜色 2.5 样式字体 2.6 基础示例 2.7 对齐 2.8 省略 2.9 划线 3.TextInput 3.1 输入类型 3.2 提示文…

基于Springboot + vue的汽车资讯网站

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

Leetcode—392.判断子序列【简单】

2023每日刷题&#xff08;四十七&#xff09; Leetcode—392.判断子序列 双指针实现代码 bool isSubsequence(char* s, char* t) {int lens strlen(s);int lent strlen(t);int left 0, right 0;if(lens 0) {return true;}while(right < lent) {if(t[right] s[left])…

Javaweb之Vue组件库Element案例分页工具栏的详细解析

4.4.3.5.3 分页工具栏 分页条我们之前做过&#xff0c;所以我们直接找到之前的案例&#xff0c;复制即可&#xff0c;代码如下&#xff1a; 其中template模块代码如下&#xff1a; <!-- Pagination分页 --> <el-paginationsize-change"handleSizeChange"c…

93基于matlab的萤火虫算法优化支持向量机(GSA-SVM)分类模型

基于matlab的萤火虫算法优化支持向量机&#xff08;GSA-SVM&#xff09;分类模型&#xff0c;以分类精度为优化目标优化SVM算法的参数c和g&#xff0c;输出分类可视化结果。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 93萤火虫算法优化支持向量机 (xiaoh…

1-算法基础-编程基础

1.基本数据类型 char ch A; char s[] "hello";2.const定义常量 const int N 1e5 9;//const定义常量&#xff0c;后续不可被修改 int a[N];3.万能头文件 C11等可用 #include<bits/stdc.h> using namespace std;4.typedef typedef long long kk; kk a[20…

反序列化漏洞(二)

目录 pop链前置知识&#xff0c;魔术方法触发规则 pop构造链解释&#xff08;开始烧脑了&#xff09; 字符串逃逸基础 字符减少 字符串逃逸基础 字符增加 实例获取flag 字符串增多逃逸 字符串减少逃逸 延续反序列化漏洞(一)的内容 pop链前置知识&#xff0c;魔术方法触…

Eaxyx 让圆球跟随鼠标移动

如果出现2023&#xff0c;代表配置成功: 进入Eaxy官方网站&#xff0c;点击文档&#xff1a; 选择 函数->绘图函数->initgraph: 可以看见initgraph&#xff08;&#xff09;函数有如下三个参数: 现在我们想生成一个1280*720大小的窗口&#xff1a; 我们需写如下代码: 但…

基于算能的国产AI边缘计算盒子8核心A53丨17.6Tops算力

边缘计算盒子 8核心A53丨17.6Tops算力 ● 可提供17.6TOPS&#xff08;INT8&#xff09;的峰值计算能力、2.2TFLOPS&#xff08;FP32&#xff09;的高精度算力&#xff0c;单芯片最高支持32路H.264 & H.265的实时解码能力。 ● 适配Caffe/TensorFlow/MxNet/PyTorch/ ONNX/…

如何解读手机APP入侵与逆向破解

如果您有耐心看完这篇文章&#xff0c;您将懂得如何着手进行app的分析、追踪、注入等实用的破解技术&#xff0c;另外&#xff0c;通过“入侵”&#xff0c;将帮助您理解如何规避常见的安全漏洞&#xff0c;文章大纲&#xff1a; 简单介绍ios二进制文件结构与入侵的原理介绍入…

Python逐步打造惊艳的折线图

大家好&#xff0c;Matplotlib可以快速轻松地使用现成的函数绘制图表&#xff0c;但是微调步骤需要花费更多精力。今天本文将介绍如何使用Matplotlib绘制吸引人的图表&#xff0c;实现折线图的惊艳变身。 1.数据 为了说明方法&#xff0c;本文使用了包含过去50年各国GDP信息的…

二维A*算法

MATLAB2016b可以正常运行 function bidirectional_ASTAR clc; clear; %% 初始化界面 n 11; % field size n x n tiles 20*20的界面 %wallpercent 0.3; % this percent of field is walls 15%的界面作为阻碍物&#xff08;墙&#xff09; cmap [1 1 1; ...% 1 - whit…

C语言易错知识点八(结构体)

结构体 世间万物&#xff0c;上至飞禽&#xff0c;下至走兽&#xff0c;全都知道一件事&#xff1a;三个臭皮匠&#xff0c;顶个诸葛亮。&#xff08;假的&#xff09;即使是处于人类前沿的编程语言也知道要把数据联合在一起&#xff0c;于是便有了数组&#xff0c;结构体&…