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

执行结果

相关推荐
学Java的bb16 分钟前
MybatisPlus
java·开发语言·数据库
讓丄帝愛伱17 分钟前
Mybatis Log Free插件使用
java·开发语言·mybatis
problc17 分钟前
Spring Cloud OpenFeign + Nacos 实战教程:像调用本地方法一样调用远程微服务
spring·spring cloud·微服务
重生之我要当java大帝18 分钟前
java微服务-尚医通-编写医院设置接口上
java·数据库·微服务
夫唯不争,故无尤也19 分钟前
Tomcat 内嵌启动时找不到 Web 应用的路径
java·前端·tomcat
心之伊始20 分钟前
Netty线程模型与Tomcat线程模型对比分析
java·开发语言
gaoshan1234567891022 分钟前
‌MyBatis-Plus 的 LambdaQueryWrapper 可以实现 OR 条件查询‌
java·tomcat·mybatis
Mu.38731 分钟前
初始Spring
java·数据库·spring
葡萄城技术团队33 分钟前
突破Excel局限!SpreadJS让电子表格“活”起来
java·数据库·excel
吹个口哨写代码41 分钟前
处理文本编辑器存的json格式报错问题,对编辑器存的字段进行转换处理,再通过json返回
java·编辑器·json