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

执行结果

相关推荐
Dola_Pan1 小时前
Linux文件IO(二)-文件操作使用详解
java·linux·服务器
wang_book1 小时前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
蜗牛^^O^2 小时前
Docker和K8S
java·docker·kubernetes
从心归零3 小时前
sshj使用代理连接服务器
java·服务器·sshj
一个诺诺前行的后端程序员3 小时前
springcloud微服务实战<1>
spring·spring cloud·微服务
IT毕设梦工厂4 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
Ylucius4 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
七夜zippoe5 小时前
分布式系统实战经验
java·分布式
是梦终空5 小时前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
落落落sss5 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle