BeanPostProcessor的五大接口
BeanPostProcessor
关于对象初始化前后的回调。
public interface BeanPostProcessor {
//该方法在bean实例化完毕(且已经注入完毕),在afterPropertiesSet或自定义init方法执行之前
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//在afterPropertiesSet或自定义init方法执行之后
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InstantiationAwareBeanPostProcessor
关于对象实例化前后以及实例化后设置propertyValues的回调
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
//这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//在对象实例化完毕执行populateBean之前 如果返回false则spring不再对对应的bean实例进行自动依赖注入。
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
//这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中
//@Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
SmartInstantiationAwareBeanPostProcessor
这个接口主要是spring框架内部来使用
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
//用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
//这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器)
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
//获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
MergedBeanDefinitionPostProcessor
用来将merged BeanDefinition暴露出来的回调
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
//在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用
//这个算是将merged BeanDefinition暴露出来的一个回调
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}
DestructionAwareBeanPostProcessor
关于处理对象销毁的前置回调
应用实例:
ApplicationListenerDetector,这个类是用来注册ApplicationListener实例的,而如果销毁一个对象,不接触这里的引用
会导致无法进行回收,因此在销毁对象时,会判断如果是ApplicationListener要执行从监听器列表中移除掉。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
//这里实现销毁对象的逻辑
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
//判断是否需要处理这个对象的销毁
default boolean requiresDestruction(Object bean) {
return true;
}
}
关于BeanPostProcessor中各个回调调用的顺序
1、InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
该方法在创建对象之前会先掉用,如果有返回实例则直接使用不会去走下面创建对象的逻辑,并在之后执行
BeanPostProcessor.postProcessAfterInitialization(result, beanName)
2、SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
如果需要的话,会在实例化对象之前执行
3、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
在对象实例化完毕 初始化之前执行
4、InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
在bean创建完毕初始化之前执行
5、InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
在bean的property属性注入完毕 向bean中设置属性之前执行
6、BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
在bean初始化(自定义init或者是实现了InitializingBean.afterPropertiesSet())之前执行
7、BeanPostProcessor.postProcessAfterInitialization(result, beanName)
在bean初始化(自定义init或者是实现了InitializingBean.afterPropertiesSet())之后执行
8、其中DestructionAwareBeanPostProcessor方法的postProcessBeforeDestruction(Object bean, String beanName)会在销毁对象前执行
DestructionAwareBeanPostProcessor 中的requiresDestruction(Object bean)是用来判断是否属于当前processor处理的bean
SmartInstantiationAwareBeanPostProcessor中的predictBeanType(Class<?> beanClass, String beanName)是用来预判类型的
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(exposedObject, beanName)
这个方法仅仅是在这一步是作为一个ObjectFactory封装起来放到singletonFactories中的,
仅在并发情况下 刚好在当前对象设置进去,而另一个bean创建需要getBean获取时才会立即执行
因此这一步的顺序是不一定的,有可能永远不会执行(无并发循坏依赖对象创建的场景)
可能在3之后对象实例化完毕执行addSingleton(beanName, singletonObject);之前执行到
因此这三个方法没有严格的顺序意义
BeanPostProcessor的五大接口的更多相关文章
- hibernate的五大接口
Hibernate有五大核心接口,分别是:Session Transaction Query SessionFactoryConfiguration .这五个接口构成了Hibernate运行的基本要素 ...
- Spring容器中bean的生命周期以及关注spring bean对象的后置处理器:BeanPostProcessor(一个接口)
Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.将 Bean 实例传递给 ...
- 谈谈Spring中的BeanPostProcessor接口
一.前言 这几天正在复习Spring的相关内容,在了解bean的生命周期的时候,发现其中涉及到一个特殊的接口--BeanPostProcessor接口.由于网上没有找到比较好的博客,所有最后花了好 ...
- spring源码:BeanPostProcessor(li)
在spring管理Bean的初始化过程中,除了正常管理bean的实例化(初始化.参数注入等)外,还对外提供了丰富的对Bean操作的扩展.例如自定义初始化操作,自定义容器退出时Bean的销毁操作等等.这 ...
- spring中基础核心接口总结
spring中基础核心接口总结理解这几个接口,及其实现类就可以快速了解spring,具体的用法参考其他spring资料 1.BeanFactory最基础最核心的接口重要的实现类有:XmlBeanFac ...
- Spring之InstantiationAwareBeanPostProcessor接口介绍
InstantiationAwareBeanPostProcessor接口是BeanPostProcessor的子接口,通过接口字面意思翻译该接口的作用是感知Bean实例话的处理器.实际上该接口的 ...
- spring扩展点之一:BeanFactoryPostProcessor和BeanPostProcessor
一.BeanFactoryPostProcessor和BeanPostProcessor的区别 BeanFactoryPostProcessor和BeanPostProcessor都是spring初始 ...
- 【原】通过Spring结合Cglib处理非接口代理
前言: 之前做的一个项目,虽然是查询ES,但内部有大量的逻辑计算,非常耗时,而且经常收到JVM峰值告警邮件.分析了一下基础数据每天凌晨更新一次,但查询和计算其实在第一次之后就可以写入缓存,这样后面直接 ...
- 简单分析BeanPostProcessor
1. 什么是BeanPostProcessorBeanPostProcessor是一个接口,有两个方法,分别是:Object postProcessBeforeInitialization(Objec ...
随机推荐
- 关于WPS页面横向问题
上图 即可进行横向竖向页面设置
- 从装饰者模式的理解说JAVA的IO包
1. 装饰者模式的详解 装饰者模式动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性 的替代方案. 装饰者模式设计类之间的关系: 其 中Component是一个超类,ConcreteC ...
- 【bzoj5147】casino 区间dp
题目描述 赌城拉斯维加斯的米高梅大赌场最近推出了一种新式赌法.它的玩法是由庄家设局(所用赌具是一批五颜六色的筹码),赌徒只要交付一定数额的赌资即可入局.开赌前庄家将手中的筹码依次排开铺成一排构成一局, ...
- C++解析(28):异常处理
0.目录 1.C语言异常处理 2.C++中的异常处理 3.小结 1.C语言异常处理 异常的概念: 程序在运行过程中可能产生异常 异常(Exception)与 Bug 的区别 异常是程序运行时可预料的执 ...
- Unity3D手游开发日记(3) - 场景加载进度条的完美方案
我以为做个进度条很简单,分分钟解决,结果折腾了一天才搞定,Unity有很多坑,要做完美需要逐一解决. 问题1:最简单的方法不能实现100%的进度 用最简单的方法来实现,不能实现100%的进度,原因是U ...
- smarty调用php函数
模板书写: {'param1'|functionName:'param2':'param3'} php函数原型: echo functionName('param1','param2','param3 ...
- 前端基础----jquery
一.jQuery是什么? <1> jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. <2>jQuery是继 ...
- CSS中background样式的repeat和no-repeat
自http://blog.sina.com.cn/s/blog_98eef7830101cv8t.html获取的知识,特此感谢. <!DOCTYPE html> <html lang ...
- 洛谷P2398 GCD SUM (数学)
洛谷P2398 GCD SUM 题目描述 for i=1 to n for j=1 to n sum+=gcd(i,j) 给出n求sum. gcd(x,y)表示x,y的最大公约数. 输入输出格式 输入 ...
- chrome 浏览器如何安装草料二维码
https://cli.im/news/6527 实测有效