当前位置: 首页 > news >正文

Spring BeanPostProcessor

BeanPostProcessor源码原理

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

public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}

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

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

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

使用时机

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

	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)方法。

    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管理器

@Slf4j
@Component
public class PluginManager implements BeanPostProcessor {//定义一个数据处理器Map,用于存储和数据类型绑定的数据处理器对象private static final Map<String, DataProcessor> dataProcessorMap = new HashMap<>();@Overridepublic 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接口

public interface DataProcessor {//获取数据类型String getDataType();//实现对应数据类型的业务处理逻辑void process(Object obj);
}

3)自定义类实现DataProcess接口

@Slf4j
@Component
public class TestAProcessorOne implements DataProcessor{@Overridepublic String getDataType() {return DataType.One;}@Overridepublic void process(Object obj) {//对应的业务逻辑 TODOSystem.out.println("TestAProcessor processOne"+obj);}
}
@Slf4j
@Component
public class TestAProcessorTwo implements DataProcessor{@Overridepublic String getDataType() {return DataType.Two;}@Overridepublic void process(Object obj) {//对应的业务逻辑 TODOSystem.out.println("TestAProcessor processTwo" + obj);}
}

4)测试工厂方法

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

http://www.lqws.cn/news/137989.html

相关文章:

  • 大数据学习(130)-zookeeper
  • 深度解析ArrayList
  • LLM:Scaling Law
  • java判断一个字符串(如 str1)是否在给定的一组字符串
  • el-table 树形数据,子行数据可以异步加载
  • Vue指令修饰符、v-bind对样式控制的增强、computed计算属性、watch监视器
  • Deepfashion2 数据集使用笔记
  • MyBatis-Plus LambdaQuery 高级用法:JSON 路径查询与条件拼接的全场景解析
  • sqli-labs靶场38-45关(堆叠注入)
  • 2025年五一数学建模竞赛A题-支路车流量推测问题详细建模与源代码编写(一)
  • fmod产生的误差应该如何解决?
  • Android studio初体验
  • yoloe优化:可支持点提示进行检测分割
  • AI系统提示词:Claude 4 Opus
  • 《PyTorch Hub:解锁深度学习模型的百宝箱》
  • Linux网络socket套接字(上)(2)
  • 【Linux】线程同步
  • 如何轻松地将文件从 PC 传输到 iPhone?
  • c++ STL 仿函数和适配器(算法常用)
  • 在树莓派上添加音频输入设备的几种方法
  • Deepin 安装 Nginx
  • 【JVM】Java类加载机制
  • fastadmin+workman环境搭建
  • Rust学习(1)
  • [Java 基础]枚举
  • Linux操作系统shell脚本
  • [Java 基础]面向对象-多态
  • 关于物联网的基础知识(一)
  • 职坐标IT教育物联网全栈开发实战:传感器到云平台全链路
  • ‌RF Choke(射频扼流圈)