Mr. Cappuccino的第61杯咖啡——Spring之BeanPostProcessor

Spring之BeanPostProcessor

    • 概述
    • 基本使用
      • 项目结构
      • 项目代码
      • 运行结果
      • 源代码
    • 常用处理器
      • 项目结构
      • 项目代码
      • 执行结果

概述

BeanPostProcessor:Bean对象的后置处理器,负责对已创建好的bean对象进行加工处理;

BeanPostProcessor中的两个核心方法:
postProcessBeforeInitialization:在每个bean对象的初始化方法执行之前执行该方法,如InitializingBean的afterPropertiesSet方法;
postProcessAfterInitialization:在每个bean对象的初始化方法执行之后执行该方法,如InitializingBean的afterPropertiesSet方法;

基本使用

项目结构

在这里插入图片描述

项目代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>spring-bean-post-processor</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

AutowireBean.java

package com.spring.bean;

import org.springframework.stereotype.Component;

/**
 * @author honey
 * @date 2023-08-11 16:50:19
 */
@Component
public class AutowireBean {

    public void autowire(){
        System.out.println("AutowireBean 执行autowire()");
    }

}

UserBean.java

package com.spring.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @author honey
 * @date 2023-08-11 16:48:33
 */
@Component
public class UserBean {

    private AutowireBean autowireBean;

    public UserBean() {
        System.out.println("UserBean 执行构造方法");
    }

    @Autowired
    public void setAutowireBean(AutowireBean autowireBean) {
        System.out.println("UserBean 依赖注入:" + autowireBean);
        this.autowireBean = autowireBean;
    }

    @PostConstruct
    public void init() {
        System.out.println("UserBean 执行init()");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("UserBean 执行destroy()");
    }

    public void autowire() {
        System.out.println("UserBean 执行autowire()");
        autowireBean.autowire();
    }
}

MyBeanPostProcessor.java

package com.spring.processor;

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

/**
 * @author honey
 * @date 2023-08-11 16:42:27
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    private final String beanName = "userBean";

    /**
     * 在每个bean对象的初始化方法执行之前执行
     *
     * @param bean     bean对象
     * @param beanName bean名称
     * @return 在调用init初始化之前,可以修改原有bean对象,如果返回为null,则直接返回原有bean对象
     * @throws BeansException BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("UserBean 执行postProcessBeforeInitialization方法");
            System.out.println("UserBean 实例对象:" + bean);
        }
        return bean;
    }

    /**
     * 在每个bean对象的初始化方法执行之后执行
     *
     * @param bean     bean对象
     * @param beanName bean名称
     * @return 在调用init初始化之后,可以修改原有bean对象,如果返回为null,则直接返回原有bean对象
     * @throws BeansException BeansException
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (this.beanName.equals(beanName)) {
            System.out.println("UserBean 执行postProcessAfterInitialization方法");
            System.out.println("UserBean 实例对象:" + bean);
        }
        return bean;
    }
}

SpringConfig.java

package com.spring.config;

import org.springframework.context.annotation.ComponentScan;

/**
 * @author honey
 * @date 2023-08-11 16:51:26
 */
@ComponentScan(value = {"com.spring.bean,com.spring.processor"})
public class SpringConfig {

}

SpringTest01.java

package com.spring.test;

import com.spring.bean.UserBean;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author honey
 * @date 2023-08-11 16:53:30
 */
public class SpringTest01 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
        System.out.println("--------------------------");
        System.out.println("UserBean 实例对象:" + userBean);
        userBean.autowire();
        System.out.println("--------------------------");
        applicationContext.close();
    }
}

运行结果

在这里插入图片描述

从运行结果可以看到,postProcessBeforeInitialization方法在init()方法执行之前执行,而postProcessAfterInitialization方法在init()方法执行之后执行。


在postProcessBeforeInitialization和postProcessAfterInitialization方法中可以对原有的bean对象进行修改,如果方法的返回值为null,则不会对原有的bean对象进行修改。

第一种情况:返回值为原有bean对象

在这里插入图片描述

第二种情况:返回值为null

在这里插入图片描述

运行结果:

在这里插入图片描述


第三种情况:返回值不是原有的bean对象

在这里插入图片描述

运行结果:

在这里插入图片描述


源代码


AbstractAutowireCapableBeanFactory.java

在这里插入图片描述

在这里插入图片描述


常用处理器

AutowiredAnnotationBeanPostProcessor:处理@Autowired注解
CommonAnnotationBeanPostProcessor:处理@Resource注解

项目结构

在这里插入图片描述

项目代码

OrderBean.java

package com.spring.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

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

/**
 * @author honey
 * @date 2023-08-12 19:16:27
 */
@Component
public class OrderBean {

    private AutowireBean autowireBean;

    public OrderBean() {
        System.out.println("OrderBean 执行构造方法");
    }

    @Autowired
    public void setAutowireBean1(AutowireBean autowireBean) {
        System.out.println("OrderBean @Autowired依赖注入:" + autowireBean);
        this.autowireBean = autowireBean;
    }

    @Resource
    public void setAutowireBean2(AutowireBean autowireBean) {
        System.out.println("OrderBean @Resource依赖注入:" + autowireBean);
        this.autowireBean = autowireBean;
    }

    @PostConstruct
    public void init() {
        System.out.println("OrderBean 执行init()");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("OrderBean 执行destroy()");
    }

    public void autowire() {
        System.out.println("OrderBean 执行autowire()");
        autowireBean.autowire();
    }

}

SpringTest02.java

package com.spring.test;

import com.spring.bean.AutowireBean;
import com.spring.bean.OrderBean;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author honey
 * @date 2023-08-12 19:20:53
 */
public class SpringTest02 {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        // 注册bean对象
        applicationContext.registerBean("orderBean", OrderBean.class);
        applicationContext.registerBean("autowireBean", AutowireBean.class);
        // 处理@Autowired注解
        applicationContext.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        // 处理@Resource注解
        applicationContext.registerBean(CommonAnnotationBeanPostProcessor.class);
        applicationContext.refresh();
        OrderBean orderBean = applicationContext.getBean("orderBean", OrderBean.class);
        System.out.println("--------------------------");
        System.out.println("AsyncBean 实例对象:" + orderBean);
        orderBean.autowire();
        System.out.println("--------------------------");
        applicationContext.close();
    }
}

执行结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React Dva项目小优化之redux-action

之前 我们讲过 models 接下啦 我们来给大家讲一个新的库 这个库的话 有最好 没有影响也不大 它主要是帮助我们处理 action的 我们直接在 GitHub 官网上搜索 redux-action 我们搜出来 第一个就是 从星数来看 还是非常优秀的 我们拉下来 找到这个Documentation 然后点击进去 进…

一、Dubbo 简介与架构

一、Dubbo 简介与架构 1.1 应用架构演进过程 单体应用&#xff1a;JEE、MVC分布式应用&#xff1a;SOA、微服务化 1.2 Dubbo 简介一种分布式 RPC 框架&#xff0c;对专业知识&#xff08;序列化/反序列化、网络、多线程、设计模式、性能优化等&#xff09;进行了更高层的抽象和…

BUUCTF [MRCTF2020]Ezpop解题思路

题目代码 Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack It! class Modifier {protected $var;publi…

日精注塑机联网

不改造程序的话&#xff0c;日精支持输出CSV和txt数据作为其他软件的接口。 改造后可以支持63协议。 在软件层面日精也有专用的软件&#xff0c;可以看到其实设备厂家提供的软件功能已经非常丰富了&#xff0c;但这类软件最大的缺点是只能自己家的机器使用&#xff0c;要想其他…

ARTS 挑战打卡的第8天 ---volatile 关键字在MCU中的作用,四个实例讲解(Tips)

前言 &#xff08;1&#xff09;volatile 关键字作为嵌入式面试的常考点&#xff0c;很多人都不是很了解&#xff0c;或者说一知半解。 &#xff08;2&#xff09;可能有些人会说了&#xff0c;volatile 关键字不就是防止编译器优化的吗&#xff1f;有啥好详细讲解的&#xff1…

Blazor前后端框架Known-V1.2.12

V1.2.12 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazo…

语聚AI如何通过对话方式让AI助手执行应用软件

1 什么是应用助手&#xff1f; 应用助手可以通过对话的方式让AI助手执行应用软件的操作。 例如&#xff0c;您可以调用“Bing搜索引擎搜索”热门信息&#xff0c;然后根据这些信息总结内容。 也可以使用“抖音”应用&#xff0c;搜索热门抖音视频&#xff0c;并根据热门视频生…

JavaEE初阶:多线程 - 编程

1.认识线程 我们在之前认识了什么是多进程&#xff0c;今天我们来了解线程。 一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行 着多份代码. 引入进程这个概念&#xff0c;主要是为了解决并发编程这样的…

Visual Studio 2022 中解决使用scanf报错的方法(一劳永逸)

目录 【前言】 一、scanf报错示例 二、解决使用scanf报错的方法 解决方法1&#xff08;不推荐&#xff09; 解决方法2&#xff08;不推荐&#xff09; 解决方法3&#xff08;强烈推荐&#xff09; 第一步 第二步 第三步 三、效果演示&#xff08;方法三&#xff09; …

Vue组件库 (一):Element常用组件

Element基于Vue2.0的桌面端组件库 组件&#xff1a;组成网页的部件。例如超链接、图片、按钮等。 一、环境配置 1、下载element 在vscode工程终端下下载。一定要注意&#xff1a;是在工程下安装&#xff01; npm install element -ui2.15.3 出现以下问题&#xff1a; 经判…

linux系统部署jenkins详细教程

一、Linux环境 1、下载war包 官网下载地址&#xff1a; https://get.jenkins.io/war-stable/2.332.4/jenkins.war 2、将war包上传至服务器 创建目录/home/ubuntu/jenkins 上传war包至该目录 3、将jenkins添加到环境变量 进入环境变量文件 vim /etc/profile # 文件下方追加…

Linux交叉编译opencv并移植ARM端

Linux交叉编译opencv并移植ARM端 - 知乎 一、安装交叉编译器 目标平台为arm7l&#xff0c;此为32位ARM架构&#xff0c;要安装合适的编译器 sudo apt install arm-linux-gnueabihf-gcc sudo apt install arm-linux-gnueabihf-g注意&#xff1a;64位ARM架构的编译器与32位ARM架…

opencv图像轮廓检测

效果展示&#xff1a; 代码部分&#xff1a; import cv2 import numpy as np img cv2.imread(C:/Users/ibe/Desktop/picture.PNG,cv2.IMREAD_UNCHANGED) # 类型转换 img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 结构元 kernel cv2.getStructuringElement(cv2.MORPH_REC…

运维监控学习笔记8

在服务器端&#xff0c;我们添加了nginx-server的主机&#xff1a; 在解决Error问题的过程中&#xff0c;我还通过zabbix_get这个命令进行了测试&#xff0c;发现是没有的&#xff0c;后来确认是在web页面配置的过程中&#xff0c;我输错了密码。 yum install zabbix-getzabbi…

快速注册微信小程序的账号

注册网站&#xff1a; 微信公众平台 1.点击该网站进行注册 2.选择小程序 3.前往注册小程序账号 4.填写相应的信息后&#xff0c;同意协议后就需要我们登录刚刚注册的邮箱 5.登录邮箱查看信息并进行激活 6.激活登录后就可以看到该页面&#xff0c;然后注册的类型为个人&#xff…

由浅入深学习Tapable

文章目录 由浅入深学习TapableTapable是什么Tapable的Hook分类同步和异步的 使用Sync*同步类型钩子基本使用bailLoopWaterfall Async*异步类型钩子ParallelSeries 由浅入深学习Tapable webpack有两个非常重要的类&#xff1a;Compiler和Compilation。他们通过注入插件的方式&a…

NPM与外部服务的集成(下)

目录 1、撤消访问令牌 2、在CI/CD工作流中使用私有包 2.1 创建新的访问令牌 持续整合 持续部署 交互式工作流 CIDR白名单 2.2 将令牌设置为CI/CD服务器上的环境变量 2.3 创建并签入特定于项目的.npmrc文件 2.4 令牌安全 3、Docker和私有模块 3.1 背景&#xff1a;运…

CSS变形与动画(二):perspctive透视效果 与 preserve-3d 3d效果(奥运五环例子)

文章目录 perspective 3d透视效果preserve-3d 3d嵌套效果例子 奥运五环 backface-visibility 背面效果 perspective 3d透视效果 perspective 指定了观察者与 z0 平面的距离&#xff0c;使具有三维位置变换的元素产生透视效果。z>0 的三维元素比正常大&#xff0c;而 z<0 …

零拷贝详解

1、在没有DMA技术之前的I/O过程是这样的&#xff1a; CPU发出对应的指令给磁盘控制器&#xff0c;然后返回磁盘控制器收到指令后&#xff0c;于是就开始准备数据&#xff0c;会把数据放入到磁盘控制器的内部缓冲区&#xff0c;然后产生中断CPU收到中断信号后&#xff0c;停下手…

Python opennsfw/opennsfw2 图片/视频 鉴黄 笔记

nsfw&#xff08; Not Suitable for Work&#xff09;直接翻译就是 工作的时候不适合看&#xff0c;真文雅 nsfw效果&#xff0c;注意底部的分数 大体流程&#xff0c;输入图片/视频&#xff0c;输出0-1之间的数字&#xff0c;一般情况下&#xff0c;Scores < 0.2 认为是非…