Spring BeanPostProcessor

BeanPostProcessor源码原理

BeanPostProcessor接口在org.springframework.beans.factory.config包下,该接口源码如下:

java 复制代码
public interface BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

postProcessBeforeInitialization:前置处理器,在bean初始化之前被调用

postProcessAfterInitialization:后置处理器,在bean初始化之后被调用

用法:所有被Spring管理的Bean,被初始化前后都会调用,实现了BeanPostProcessor接口且被Spring管理的前置及后置处理器处理。

使用时机

当创建bean实例并完成属性填充之后,会调用AbstractAutowireCapableBeanFactory类的initializeBean方法对bean进行初始化,在初始化前后会分别执行postProcessBeforeInitialization方法和postProcessAfterInitialization

java 复制代码
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		invokeAwareMethods(beanName, bean);

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

再看一下applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)的实现,getBeanPostProcessors()循环调用实现了BeanPostProcess的bean实例并执行processor.postProcessAfterInitialization(result, beanName)方法。

java 复制代码
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

BeanPostProcessor 应用场景

工厂模式中用于管理bean

1)自定义Bean管理器

java 复制代码
@Slf4j
@Component
public class PluginManager implements BeanPostProcessor {
    //定义一个数据处理器Map,用于存储和数据类型绑定的数据处理器对象
    private static final Map<String, DataProcessor> dataProcessorMap = new HashMap<>();

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, @Nullable String beanName) throws BeansException {
        if (bean instanceof DataProcessor) {
            DataProcessor dp = (DataProcessor) bean;
            dataProcessorMap.put(dp.getDataType(), dp);
            log.info("PluginManager.postProcessAfterInitialization() | size={},dataProcessorMap={}"
                    , dataProcessorMap.size(), dataProcessorMap);
        }
        return bean;
    }

    public static DataProcessor getDataPlugin(String dataType) {
        return dataProcessorMap.get(dataType);
    }
    public static Map<String, DataProcessor> getDataProcessorMap(){
        return dataProcessorMap;
    }
}

2)自定义DataProcessor接口

java 复制代码
public interface DataProcessor {
    //获取数据类型
    String getDataType();

    //实现对应数据类型的业务处理逻辑
    void process(Object obj);
}

3)自定义类实现DataProcess接口

java 复制代码
@Slf4j
@Component
public class TestAProcessorOne implements DataProcessor{
    @Override
    public String getDataType() {
        return DataType.One;
    }

    @Override
    public void process(Object obj) {
        //对应的业务逻辑 TODO
        System.out.println("TestAProcessor processOne"+obj);
        
    }
}
java 复制代码
@Slf4j
@Component
public class TestAProcessorTwo implements DataProcessor{
    @Override
    public String getDataType() {
        return DataType.Two;
    }

    @Override
    public void process(Object obj) {
        //对应的业务逻辑 TODO
        System.out.println("TestAProcessor processTwo" + obj);
        
    }
}

4)测试工厂方法

java 复制代码
@RestController
public class TestController {
    @GetMapping("/test")
    public void test(){
        Map<String, DataProcessor> dataProcessorMap = PluginManager.getDataProcessorMap();
        System.out.println(dataProcessorMap);

        DataProcessor dataPlugin = PluginManager.getDataPlugin(DataType.One);
        System.out.println(dataPlugin);
        dataPlugin.process();
    }

}
相关推荐
程序员黑豆3 小时前
Java包装类:基本类型与对象的桥梁
java·前端·ai编程
mldong7 小时前
"applicant" 契约:退回发起人的闭环设计
java·架构
月华路7 小时前
G1 垃圾回收:脏卡队列、记忆集与并发精化线程机制
java·开发语言
gugucoding8 小时前
47. 【Java】Java内存模型(JMM)与可见性
java·开发语言
zww89491118 小时前
校园跑腿系统开发实战指南:从需求分析到上线部署全流程解析
java
Fluxart.ai9 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
名字还没想好☜9 小时前
Java 线上内存泄漏排查实战:jmap 导堆、MAT 找 GC Roots 与四类常见泄漏
java·开发语言·jvm·内存泄漏
IT爱学堂11 小时前
尚硅谷 - 2025年3月Java+AI大模型应用开发
java·开发语言·人工智能
小贤plus12 小时前
SpringBoot 三大核心注解精讲:@ControllerAdvice、@RestControllerAdvice、@Validated 分组校验(实战)
java
吠品12 小时前
Java byte数组与String互转:编码细节与踩坑记录
java·linux·服务器