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

Spring之BeanPostProcessor

概述

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

BeanPostProcessor中的两个核心方法:

postProcessBeforeInitialization:在每个bean对象的初始化方法执行之前执行该方法,如InitializingBean的afterPropertiesSet方法;

postProcessAfterInitialization:在每个bean对象的初始化方法执行之后执行该方法,如InitializingBean的afterPropertiesSet方法;

基本使用

项目结构

项目代码

pom.xml

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

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

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

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

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

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

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

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();
    }
}

执行结果

相关推荐
禁默7 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood14 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑17 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb421528719 分钟前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶20 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
zfoo-framework28 分钟前
【jenkins插件】
java
风_流沙33 分钟前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
ProtonBase1 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法