网站首页 > 精选教程 正文
Spring Framework版本:5.3.x
BeanPostProcessor 在Spring框架中举足轻重,还有很多继承的类。
作用:管理Bean的生命周期:Bean实例化--->Bean初始化--->Bean使用中--->Bean销毁
在Spring 容器初始化的时候就会存在这些类执行的一个先后的问题,今天我们就把这些类的执行先后顺序进行梳理。
1. BeanPostProcessor的分类
BeanPostProcessor 作为顶层接口会有很多的继承接口和实现类,下图就是分类:
如上图所示包括 BeanPostProcessor 在内,一共有五个接口类。分成了三个功能模块。
- Bean实例化这要由InstantiationAwareBeanPostProcessor、SmartInstantiationAwareBeanPostProcessor负责。
- Bean初始化由BeanPostProcessor、MergedBeanDefinitionPostProcessor两个接口负责
- Bean销毁由DestructionAwareBeanPostProcessor接口负责
从分类可以看出来这个五个接口分别对应Bean的三个阶段:实例化、初始化、以及销毁。那么各个阶段里面的执行顺序是怎么样的我们接着往下分析
2. 接口的执行顺序
BeanPostProcessor主要负责Bean的生命周期,那么我们从获取Bean的接口入手看获取到Bean的过程中需要执行那些接口。跟踪代码最终跟踪到了 AbstractBeanFactory#doGetBean方法:
//AbstractBeanFactory#doGetBean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
复制代码
在这个当中有一个 createBean 方法。从名称可以知道是用来创建Bean的(实例化)。在这个方法里面主要有三段重要代码:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
//省略部分代码
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
复制代码
这段代码涵盖了上面五个接口的四个分别是:
InstantiationAwareBeanPostProcessor、
SmartInstantiationAwareBeanPostProcessor、BeanPostProcessor、
MergedBeanDefinitionPostProcessor。唯一的Bean的销毁,Bean的销毁是随着Spring容器销毁而销毁的。整个执行的流程和步骤如下图:
从上图的执行顺序可以看出来:
- 接口之间的执行顺序不是严格按照: 实例化->初始化->销毁 这样的严格顺序来进行。接口方法之间的顺序会有穿插的情况。
- InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法执行如果返回了对应的Bean的实例,后续的接口都不会执行了。 这里我们可以加入自定义的类。典型的例子就是动态代理的实现,可以继承当前接口并且在改方法中实现动态代理。这样在Spring 容器中的实例就是一个动态代理实例。
- DestructionAwareBeanPostProcessor 接口一般情况下是不会执行,只有当Spring容器销毁就会触发容器里面类的销毁机制。
- 同一种类型接口如果有继承 PriorityOrdered 和Ordered进行排序。
Tips: 对于基于BeanPostProcessor自定义开发来说,主要用于自定义方法或者属性类上面的注解。这里举两个Spring的例子:
AutowiredAnnotationBeanPostProcessor 处理@Autowired, @Value注解,
AsyncAnnotationBeanPostProcessor 处理 @Async注解。这些注解都是在属性上或者方法上面。
3. 总结
- BeanPostProcessor 接口主要是启动的时候添加到Spring容器中提供给后续的使用
- BeanPostProcessor 接口执行主要发生在获取Bean的流程中(Bean的生命周期)
- 自定义开发可以参照Spring已有的实现,能够更加明了的知道如何进行进一步拓展使用
猜你喜欢
- 2025-05-21 Spring应用上下文 ApplicationContext
- 2025-05-21 Spring Boot3 中接口防抖操作全解析
- 2025-05-21 jmeter接口测试教程
- 2025-05-21 使用httpclient post请求中文乱码解决办法
- 2025-05-21 前端请求一到,后端就乱套?揭秘 Spring MVC 底层调用全流程!
- 2025-05-21 在 Spring Boot3 中轻松解决接口跨域访问问题
- 2025-05-21 SpringBoot 数据验证与表单处理全面指南(史上最全)
- 2025-05-21 原来大牛们口中的接口Mock测试是长这样的,今天我终于搞懂了
- 2025-05-21 3 分钟Java 开发 MCP Server,一键打通飞书机器人消息发送通道!
- 2025-05-21 Java 调用 DeepSeek 模型的完整示例及特点
你 发表评论:
欢迎- 最近发表
-
- 我的世界光影MOD下载(我的世界光影mod下载安装)
- 我的世界1.7/1.8VoxelMap小地图MOD下载
- 我的世界1.7.10多世界 整合包(我的世界1.7.10forge整合包)
- 我的世界1.8最好用的修改器下载(我的世界1.8最好用的修改器下载安装)
- 我的世界更多弯曲动作MOD下载(我的世界更多弯曲动作mod下载手机版)
- 我的世界龙珠MOD下载(我的世界龙珠模组整合包下载)
- 我的世界1.7.10以太2 下载(我的世界以太2mod1.12.2)
- 我的世界虚拟人生MOD下载分享(我的世界虚拟人生下载安装)
- 我的世界无正版账号的简单联机方法(非网易版,仅适用于局域网)
- “我的语言极限,即是我的世界的极限。” ——《On Java》书籍推荐
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)