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

Spring Boot 中关于 Bean 加载、实例化、初始化全生命周期的扩展点

一、先明确:Bean 完整生命周期

先梳理 Spring Bean 从“定义”到“销毁”的完整流程,所有扩展点都嵌入在这个流程中:

csharp 体验AI代码助手 代码解读 复制代码 1. 扫描/解析生成 BeanDefinition(Bean 定义)→ 2. 注册 BeanDefinition 到容器 → 3. 实例化 Bean(创建对象)→ 4. 属性填充(依赖注入)→ 5. 初始化前处理 → 6. 初始化(执行 init 方法)→ 7. 初始化后处理 → 8. Bean 就绪使用 → 9. 容器关闭 → 10. 销毁 Bean

二、按生命周期阶段拆解扩展点(优先级+时机+示例)

阶段 1:BeanDefinition 处理阶段(实例化前,最高优先级)

核心目标:修改/新增/删除 BeanDefinition,不涉及 Bean 实例
该阶段扩展点优先级:BeanDefinitionRegistryPostProcessor>BeanFactoryPostProcessor

1. BeanDefinitionRegistryPostProcessor(顶级扩展点)

  • 核心作用:动态注册/修改/删除 BeanDefinition(Spring 最早的扩展点)
  • 执行时机:扫描生成 BeanDefinition 后 → Bean 实例化前
  • 优先级:最高(优先于所有 BeanFactoryPostProcessor)
  • 典型场景:Spring Boot 自动配置、MyBatis Mapper 扫描、动态注册 Bean

实战示例:动态注册 UserService Bean

java 体验AI代码助手 代码解读 复制代码 @Component public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { // 1. 构建 BeanDefinition(描述 UserService 的定义) RootBeanDefinition userServiceDefinition = new RootBeanDefinition(UserService.class); // 可选:设置 Bean 属性(如作用域、初始化方法) userServiceDefinition.setScope(BeanDefinition.SCOPE_SINGLETON); userServiceDefinition.setInitMethodName("init"); // 2. 注册 BeanDefinition 到容器(Bean 名称:userService) registry.registerBeanDefinition("userService", userServiceDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 可选:对 BeanFactory 做额外配置(优先级低于上面的方法) beanFactory.registerSingleton("testBean", new TestBean()); } } // 无任何 Spring 注解的业务类 public class UserService { public void init() { System.out.println("UserService 初始化方法执行"); } public void sayHello() { System.out.println("动态注册的 UserService 就绪"); } } // 测试 @SpringBootApplication public class TestApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(TestApplication.class); UserService userService = context.getBean(UserService.class); userService.sayHello(); // 输出:动态注册的 UserService 就绪 } }

2. BeanFactoryPostProcessor(BeanFactory 配置修改)

  • 核心作用:修改已注册的 BeanDefinition 属性(如修改作用域、属性值),不能新增 BeanDefinition
  • 执行时机:BeanDefinitionRegistryPostProcessor 执行后 → Bean 实例化前
  • 优先级:低于 BeanDefinitionRegistryPostProcessor
  • 典型场景:修改 Bean 配置、占位符替换(如 ${spring.datasource.url})

实战示例:修改已有 BeanDefinition 的属性

java 体验AI代码助手 代码解读 复制代码 @Component public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { // 1. 获取已注册的 BeanDefinition(假设容器中有 "userService" Bean) BeanDefinition userServiceDef = beanFactory.getBeanDefinition("userService"); // 2. 修改属性:将单例改为原型 userServiceDef.setScope(BeanDefinition.SCOPE_PROTOTYPE); // 3. 设置自定义属性 MutablePropertyValues propertyValues = userServiceDef.getPropertyValues(); propertyValues.add("name", "自定义名称"); } }

阶段 2:Bean 实例化+属性填充阶段(初始化前)

核心目标:干预 Bean 实例的创建和依赖注入
该阶段扩展点:InstantiationAwareBeanPostProcessor(BeanPostProcessor 子接口)

InstantiationAwareBeanPostProcessor(实例化+属性填充拦截)

  • 核心作用:拦截 Bean 实例化、属性填充过程,可替换 Bean 实例、修改注入属性
  • 执行时机
  1. postProcessBeforeInstantiation:Bean 实例化前(替代默认实例化逻辑)
  2. postProcessAfterInstantiation:Bean 实例化后 → 属性填充前
  3. postProcessProperties:属性填充时(修改注入的属性值)
  • 优先级:高于普通 BeanPostProcessor
  • 典型场景:自定义依赖注入、字段注解解析(如 @Value、@Autowired)

实战示例:拦截 UserService 实例化和属性填充

java 体验AI代码助手 代码解读 复制代码 @Component public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { // 1. 实例化前拦截(可直接返回自定义实例,跳过默认实例化) @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("UserService 实例化前拦截"); // 可选:返回自定义实例(替代 Spring 自动实例化) // return new UserService(); } return null; // 返回 null 则走默认实例化逻辑 } // 2. 实例化后拦截(属性填充前) @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("UserService 实例化后,属性填充前"); } return true; // 返回 true 才会执行属性填充 } // 3. 属性填充拦截(修改注入的属性值) @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("UserService 属性填充拦截"); // 修改属性值(假设 UserService 有 name 字段) MutablePropertyValues mutablePvs = (MutablePropertyValues) pvs; mutablePvs.add("name", "拦截后修改的名称"); } return pvs; } }

阶段 3:Bean 初始化阶段(实例化+属性填充后)

核心目标:修改 Bean 实例、执行初始化逻辑
该阶段扩展点优先级:BeanPostProcessor.postProcessBeforeInitialization> 自定义初始化方法 >BeanPostProcessor.postProcessAfterInitialization

1. BeanPostProcessor(初始化前后拦截)

  • 核心作用:拦截所有 Bean 的初始化过程,修改 Bean 实例
  • 执行时机
  1. postProcessBeforeInitialization:初始化方法(如 @PostConstruct、init-method)执行前
  2. postProcessAfterInitialization:初始化方法执行后
  • 优先级:可通过 @Order 注解控制多个 BeanPostProcessor 的执行顺序
  • 典型场景:AOP 代理创建、Bean 增强(如事务代理、缓存代理)

实战示例:拦截 UserService 初始化过程

java 体验AI代码助手 代码解读 复制代码 @Component @Order(1) // 控制优先级(数字越小优先级越高) public class CustomBeanPostProcessor implements BeanPostProcessor { // 1. 初始化前处理 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("UserService 初始化前处理"); } return bean; // 返回修改后的 Bean 实例 } // 2. 初始化后处理(AOP 代理通常在这里创建) @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("userService".equals(beanName)) { System.out.println("UserService 初始化后处理"); // 可选:返回代理对象(如 JDK 动态代理) // return Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), (proxy, method, args) -> { // System.out.println("方法执行前增强"); // return method.invoke(bean, args); // }); } return bean; } }

2. 自定义初始化方法(3 种方式)

  • 核心作用:执行 Bean 专属的初始化逻辑
  • 执行时机:BeanPostProcessor 前置处理后 → 后置处理前
  • 优先级:同一 Bean 内优先级:@PostConstruct>InitializingBean.afterPropertiesSet()>init-method

实战示例:3 种初始化方法对比

java 体验AI代码助手 代码解读 复制代码 @Component public class UserService implements InitializingBean { private String name; // 方式 1:@PostConstruct 注解(最常用) @PostConstruct public void postConstructInit() { System.out.println("UserService @PostConstruct 初始化"); } // 方式 2:实现 InitializingBean 接口 @Override public void afterPropertiesSet() throws Exception { System.out.println("UserService InitializingBean 初始化"); } // 方式 3:XML/注解指定 init-method(传统方式) public void initMethod() { System.out.println("UserService init-method 初始化"); } // getter/setter 省略 } // 配置类指定 init-method(如果不用注解的话) @Configuration public class AppConfig { @Bean(initMethod = "initMethod") public UserService userService() { return new UserService(); } }

阶段 4:Bean 销毁阶段(容器关闭时)

核心目标:执行 Bean 销毁前的清理逻辑
扩展点优先级:@PreDestroy>DisposableBean.destroy()>destroy-method

自定义销毁方法(3 种方式)

  • 核心作用:释放资源(如关闭连接池、销毁线程)
  • 执行时机:Spring 容器关闭时(调用context.close()
  • 典型场景:资源清理、连接关闭

实战示例:3 种销毁方法对比

java 体验AI代码助手 代码解读 复制代码 @Component public class UserService implements DisposableBean { // 方式 1:@PreDestroy 注解 @PreDestroy public void preDestroy() { System.out.println("UserService @PreDestroy 销毁"); } // 方式 2:实现 DisposableBean 接口 @Override public void destroy() throws Exception { System.out.println("UserService DisposableBean 销毁"); } // 方式 3:XML/注解指定 destroy-method public void destroyMethod() { System.out.println("UserService destroy-method 销毁"); } } // 配置类指定 destroy-method @Configuration public class AppConfig { @Bean(destroyMethod = "destroyMethod") public UserService userService() { return new UserService(); } } // 测试销毁 public class TestDestroy { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(TestApplication.class); // 关闭容器触发销毁 context.close(); } }

http://bjypfp.mpmpc.cn/ http://tjypfp.mpmpc.cn/ http://shypfp.mpmpc.cn/ http://zqypfp.mpmpc.cn/ http://tyypfp.mpmpc.cn/ http://sjzypfp.mpmpc.cn/ http://hhhtypfp.mpmpc.cn/ 关于沈阳开具医药品费发票-沈阳Home http://ccypfp.mpmpc.cn/ http://hebypfp.mpmpc.cn/ http://njypfp.mpmpc.cn/ http://szypfp.mpmpc.cn/ http://hzypfp.mpmpc.cn/ http://hfypfp.mpmpc.cn/ http://xmypfp.mpmpc.cn/ http://fzypfp.mpmpc.cn/ http://ncypfp.mpmpc.cn/ http://jnypfp.mpmpc.cn/

三、所有扩展点优先级总览(从高到低)

扩展点/方法执行阶段核心能力
BeanDefinitionRegistryPostProcessorBeanDefinition 注册后新增/修改/删除 BeanDefinition
BeanFactoryPostProcessorBeanDefinition 处理后修改 BeanDefinition 属性
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiationBean 实例化前替换 Bean 实例
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationBean 实例化后控制是否执行属性填充
InstantiationAwareBeanPostProcessor.postProcessProperties属性填充时修改注入的属性值
BeanPostProcessor.postProcessBeforeInitialization初始化前Bean 实例增强(如赋值)
@PostConstruct初始化中(最高)注解式初始化逻辑
InitializingBean.afterPropertiesSet()初始化中(中间)接口式初始化逻辑
init-method初始化中(最低)配置式初始化逻辑
BeanPostProcessor.postProcessAfterInitialization初始化后Bean 代理创建(如 AOP)
@PreDestroy销毁前(最高)注解式销毁逻辑
DisposableBean.destroy()销毁前(中间)接口式销毁逻辑
destroy-method销毁前(最低)配置式销毁逻辑

四、典型应用场景总结

业务需求推荐扩展点
动态注册 BeanBeanDefinitionRegistryPostProcessor
修改 Bean 配置(如作用域)BeanFactoryPostProcessor
自定义依赖注入/拦截实例化InstantiationAwareBeanPostProcessor
Bean 增强(如 AOP、缓存)BeanPostProcessor(后置初始化)
Bean 专属初始化逻辑@PostConstruct / InitializingBean
资源清理/连接关闭@PreDestroy / DisposableBean

五、关键注意事项

  1. 避免提前实例化 Bean:在BeanDefinitionRegistryPostProcessor/BeanFactoryPostProcessor中,不要调用beanFactory.getBean(),否则会触发 Bean 提前实例化,导致扩展点失效;
  2. 优先级控制:多个同类型扩展点可通过@Order注解或实现Ordered接口控制执行顺序(数字越小优先级越高);
  3. 性能影响:顶级扩展点(如 BeanDefinitionRegistryPostProcessor)执行时机早,复杂逻辑会影响容器启动速度;
  4. 代理对象注意:BeanPostProcessor 后置处理返回的代理对象,才是容器最终使用的 Bean 实例。

总结

  1. 核心逻辑:Spring Bean 扩展点围绕“定义-实例化-初始化-销毁”全生命周期设计,越靠前的扩展点越能影响 Bean 的“定义”,越靠后的扩展点越能影响 Bean 的“实例”;
  2. 优先级核心BeanDefinitionRegistryPostProcessor是最高优先级扩展点,可动态注册 Bean;BeanPostProcessor是最常用扩展点,可增强 Bean 实例;
  3. 实战选型:根据需求选择对应阶段的扩展点——改定义用前序扩展点,改实例用后序扩展点;
  4. 核心价值:这些扩展点是 Spring 灵活性的核心体现,Spring Boot 自动配置、MyBatis/Dubbo 整合 Spring 都基于这些扩展点实现。

掌握这些扩展点,你不仅能读懂 Spring 底层源码,还能自定义灵活的 Bean 管理逻辑,比如封装自己的 Starter、实现自定义注解解析等。

http://www.jsqmd.com/news/470642/

相关文章:

  • ROS1+VINS-fusion+RTAB-Map 程序部署记录
  • 【干货】字节大佬:教培行业销售运营全景作战地图
  • 2026年苏州口碑好的家教老师联系方式,全托补习班/一对一家教试听课/师范家教/一对一/全托一对一,家教机构联系方式 - 品牌推荐师
  • 电子商务行业内哪个环节容易遇到攻击
  • UA-Glo® 荧光法细胞活力检测试剂盒技术原理与应用
  • 五:MySQL 索引使用优化指南:何时建、怎么建、怎么用
  • 虚幻引擎资源查看工具全面解析:从新手入门到高级应用实战指南
  • 2026年知名的ALD技术工厂推荐:ALD工艺开发/ALD原子层沉积高口碑品牌推荐 - 行业平台推荐
  • 联发科牵手星链:紧急警报直连太空
  • 2026年分期乐天虹提货券回收价格表 - 京回收小程序
  • 企业AI大脑是什么?企业落地前先回答的 5 个关键问题
  • AI写专著的秘密武器,实用工具大集合,开启高效写作模式
  • 揭秘AI专著撰写工具!功能对比分析,选对工具事半功倍
  • 代码反混淆实战指南:如何用AST技术快速还原JavaScript代码
  • 2026年热门的二轴程控平面磨床公司推荐:精密台湾型高精度平面磨床品牌厂家哪家靠谱 - 行业平台推荐
  • 掌握AI专著写作工具,快速生成创新性专著,提升学术影响力
  • 2026年口碑好的打包丝公司推荐:退火丝/黑色退火丝/退火调直丝厂家推荐哪家好 - 行业平台推荐
  • ML梅花联轴器哪家研发
  • 2026 实测10款降AI率工具!知网/维普/Turnitin/QuillBot降AI率效果大比拼!
  • 网络代理相关
  • RePKG:Wallpaper Engine资源处理的效率革命工具
  • AI专著生成攻略!实用工具大盘点,助你轻松完成著作
  • 用Openclaw小龙虾自动发布小红书!!!Ubuntu
  • 如何用ExifToolGui批量重命名照片:让摄影文件管理不再繁琐
  • Python基于flask的演唱会在线票务预订平台
  • 抖音直播回放下载工具:从痛点解决到企业级应用的全攻略
  • 三菱PLC恒压供水程序开发分享
  • 火语言 RPA:元宝 AI 来源参考网址采集案例(GEO 优化)
  • 深入理解 Java HashMap 扩容机制:从源码到原理全解析
  • 4步实现高效直播内容保存:面向内容创作者的抖音直播下载与管理工具