作用

BeanPostProcessor,顾名思义是bean后置处理器,是 Spring 的扩展点之一。通过自定义 BeanPostProcessor 可以实现对 Bean 的修改,用于在bean实例化后,要初始化的前后对bean进行处理

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

执行时机

在bean被实例化出来,并且注入属性后,会调用initializeBean方法去初始化bean,在initializeBean方法中会分别调用BeanPostProcessor接口中的两个方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 调用Aware接口方法invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 调用bean后置处理器的postProcessBeforeInitialization方法wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 初始化bean,调用init方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {// 调用bean后置处理器的postProcessAfterInitialization方法wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

应用

Spring 中有一个类 ApplicationContextAwareProcessor,该类实现了 BeanPostProcessor 接口,是用来判断bean是否实现了各个Aware接口。

class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;/*** Create a new ApplicationContextAwareProcessor for the given context.*/public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());}@Override@Nullablepublic Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {AccessControlContext acc = null;if (System.getSecurityManager() != null &&(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}if (acc != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareInterfaces(bean);return null;}, acc);}else {invokeAwareInterfaces(bean);}return bean;}private void invokeAwareInterfaces(Object bean) {// 判断是否实现了各个 Aware 接口if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}}

比如实现EnvironmentAware接口的bean在该Processor内会调用EnvironmentAware接口的setEnvironment方法,并把spring容器内部的ConfigurableEnvironment传递进去。一般最常用的就是bean实现ApplicationContextAware接口,这样ApplicationContextAwareProcessor就会将ApplicationContext设置到该bean里。

Spring扩展之BeanPostProcessor相关推荐

  1. 【小家Spring】注意BeanPostProcessor启动时对依赖Bean的“误伤”陷阱(is not eligible for getting processed by all...)

    每篇一句 祝大家五一国际劳动节快乐~你是在快乐的撸码,还是在快乐的浪呢? 本文已被https://yourbatman.cn收录:程序员专用网盘https://wangpan.yourbatman.c ...

  2. spring注解驱动开发-8 Spring 扩展原理

    Spring 扩展原理 前言 BeanFactoryPostProcessor 测试实例编写 ExtConfig MyBeanFactoryPostProcessor ExtTest 源码分析 Bea ...

  3. spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入...

    <spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...

  4. 利用Spring扩展点模拟MyBatis的注解编程「知识点多多」「扩展点实战系列」- 第448篇

    历史文章(文章累计440+) <国内最全的Spring Boot系列之一> <国内最全的Spring Boot系列之二> <国内最全的Spring Boot系列之三> ...

  5. Spring系列之BeanPostProcessor分析

    在Spring系列之Bean的生命周期及相关源码中,我们最后简单使用过BeanPostProcessor,这次我们就结合源码来具体谈谈这个BeanPostProcessor的作用. 实现BeanPos ...

  6. Spring扩展点总结

    经历了一系列复杂的spring应用后,你的项目可能已经用上注解,也用上了xxx.properties,你对这神奇的用法感到欣喜,但你不知道他是怎么被实现的,现在就让我们来揭开这些神秘的面纱. Bean ...

  7. spring中的BeanPostProcessor

    1.类结构 BeanPostProcessor:允许自定义修改bean实例的工厂钩子 InstantiationAwareBeanPostProcessor:BeanPostProcessor的子接口 ...

  8. Spring中的BeanPostProcessor接口

    由方法名字也可以看出,前者在实例化及依赖注入完成后.在任何初始化代码(比如配置文件中的init-method)调用之前调用:后者在初始化代码调用之后调用. 注意: 1.接口中的两个方法都要将传入的be ...

  9. SpringBoot/Spring扩展点系列之叱咤风云BeanFactoryPostProcessor - 第428篇

    历史文章(累计400+篇文章) <国内最全的Spring Boot系列之一> <国内最全的Spring Boot系列之二> <

最新文章

  1. hdpi、mdpi、ldpi图片规格
  2. 8.2.1.3 Range 优化
  3. SimpleAdapter的用法
  4. 【高速接口-RapidIO】Xilinx SRIO IP 核详解
  5. 构造函数的五种继承方法
  6. jQuery: 合并表格中相同文本的相邻单元格
  7. php数值相加_PHP+Redis 有序集合实现 24 小时排行榜实时更新
  8. 《权力的游戏》第八季剧情翻水:超40万粉丝请愿重拍
  9. 安卓Android资源链接失败,Android资源链接失败
  10. 利用工具,促进有效沟通
  11. PickerView的使用
  12. php解析krc文件,将酷狗krc歌词解析并转换为lrc歌词php源码_PHP
  13. 采用参数服务器的分布式机器学习
  14. Excel VB脚本,下拉框多选
  15. Spring AOP 之 通知、连接点、切点、切面
  16. lbe+android6.0+免root,LBE安全大师|lbe安全大师免root下载v6.1.2482 - 欧普软件下载
  17. 直击|为防虚假信息 百合佳缘引入第三方征信查询合作
  18. 数据库-------where条件和group by.... having 过滤数据的先后顺序
  19. 购物车,TextView右上角实现红色数字变化的实现
  20. 云原生之容器编排实践-在CentOS7上安装minikube

热门文章

  1. linux串口介绍与编程
  2. 活动倒计时范例(日期倒计时例子)
  3. 数学解析Logistic回归算法
  4. html 鼠标滑过后改变文字,html+CSS实例效果(1):鼠标滑过改变文字
  5. 爱立信的5G设备订单继续激增,年内或超越华为成为第一大设备商
  6. C#实现图片放大缩小
  7. 2008服务器系统启动不了网,活用Windows Server 2008命令 解决网络疑难杂症
  8. 计算机应用大赛与bap的关系,中山学子获两岸大学生计算机应用能力与信息素养海峡赛一等奖...
  9. node.js名字由来
  10. 国内Api行业,可以内卷到什么程度?