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

Spring Bean的生命周期与作用域详解

一、Spring Bean的生命周期

Spring Bean的生命周期指的是Bean从创建到销毁的整个过程。理解这个生命周期对于正确使用Spring框架至关重要,它可以帮助我们在适当的时机执行自定义逻辑。

1. 完整的Bean生命周期阶段

Spring Bean的生命周期可以分为以下几个主要阶段:

  1. 实例化(Instantiation):容器通过构造函数或工厂方法创建Bean实例

  2. 属性填充(Populate properties):设置Bean的属性值和依赖

  3. BeanNameAware.setBeanName():如果实现了BeanNameAware接口

  4. BeanFactoryAware.setBeanFactory():如果实现了BeanFactoryAware接口

  5. ApplicationContextAware.setApplicationContext():如果实现了ApplicationContextAware接口

  6. BeanPostProcessor.postProcessBeforeInitialization():BeanPostProcessor的前置处理

  7. @PostConstruct注解的方法:执行初始化回调

  8. InitializingBean.afterPropertiesSet():如果实现了InitializingBean接口

  9. 自定义init-method:执行配置的初始化方法

  10. BeanPostProcessor.postProcessAfterInitialization():BeanPostProcessor的后置处理

  11. Bean就绪可用:此时Bean可以被正常使用

  12. @PreDestroy注解的方法:容器关闭时执行销毁回调

  13. DisposableBean.destroy():如果实现了DisposableBean接口

  14. 自定义destroy-method:执行配置的销毁方法

2. 生命周期示例代码

public class ExampleBean implements BeanNameAware, InitializingBean, DisposableBean {private String name;public ExampleBean() {System.out.println("1. 实例化Bean");}public void setName(String name) {System.out.println("2. 设置属性值");this.name = name;}@Overridepublic void setBeanName(String name) {System.out.println("3. BeanNameAware.setBeanName()");}@PostConstructpublic void postConstruct() {System.out.println("5. @PostConstruct方法");}@Overridepublic void afterPropertiesSet() {System.out.println("6. InitializingBean.afterPropertiesSet()");}public void customInit() {System.out.println("7. 自定义init-method");}@PreDestroypublic void preDestroy() {System.out.println("9. @PreDestroy方法");}@Overridepublic void destroy() {System.out.println("10. DisposableBean.destroy()");}public void customDestroy() {System.out.println("11. 自定义destroy-method");}
}// 配置类
@Configuration
public class AppConfig {@Bean(initMethod = "customInit", destroyMethod = "customDestroy")public ExampleBean exampleBean() {ExampleBean bean = new ExampleBean();bean.setName("示例Bean");return bean;}
}

3. 生命周期流程图

实例化Bean → 设置属性 → Aware接口回调 → BeanPostProcessor前置处理 → 
@PostConstruct → afterPropertiesSet → init-method → 
BeanPostProcessor后置处理 → Bean就绪可用 → 
@PreDestroy → destroy() → destroy-method

二、Spring Bean的作用域

Spring框架支持多种Bean作用域,允许开发者根据需求控制Bean的创建方式和生命周期。

1. 标准作用域

Spring提供了以下标准作用域:

  1. singleton(单例,默认)

    • 每个Spring IoC容器中一个Bean定义对应一个实例

    • 所有对该Bean的请求都返回同一个实例

    • 生命周期与容器相同

  2. prototype(原型)

    • 每次请求都创建一个新的Bean实例

    • 适用于有状态的Bean

    • Spring不管理完整的生命周期,只负责初始化

  3. request(请求)

    • 每个HTTP请求创建一个新的Bean

    • 仅适用于Web应用

    • 请求结束时销毁

  4. session(会话)

    • 每个HTTP会话创建一个Bean

    • 仅适用于Web应用

    • 会话结束时销毁

  5. application(应用)

    • 每个ServletContext生命周期创建一个Bean

    • 类似单例,但范围是ServletContext而非Spring容器

  6. websocket(WebSocket)

    • 每个WebSocket会话创建一个Bean

    • 仅适用于WebSocket应用

2. 作用域配置示例

XML配置方式:
<bean id="accountService" class="com.example.AccountService" scope="prototype"/>
Java注解方式:
@Bean
@Scope("prototype")
public AccountService accountService() {return new AccountService();
}
使用@Scope注解:
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeService {// ...
}

3. 作用域选择建议

  1. 无状态服务:使用singleton(默认),性能最佳

  2. 有状态组件:使用prototype,避免并发问题

  3. Web相关数据:根据需要使用request、session等作用域

  4. 线程安全考虑:prototype作用域可以避免线程安全问题,但会增加创建开销

4. 自定义作用域

Spring还允许注册自定义作用域:

public class ThreadScope implements Scope {// 实现Scope接口方法
}// 注册自定义作用域
ConfigurableBeanFactory factory = (ConfigurableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
factory.registerScope("thread", new ThreadScope());// 使用自定义作用域
@Bean
@Scope("thread")
public MyBean myBean() {return new MyBean();
}

三、生命周期与作用域的关系

不同作用域的Bean生命周期有所不同:

  1. singleton

    • 容器启动时初始化(默认懒加载除外)

    • 容器关闭时销毁

    • 完整的生命周期回调

  2. prototype

    • 每次请求时初始化

    • 容器不跟踪实例,不会调用销毁方法

    • 只有部分生命周期回调

  3. request/session

    • 请求/会话开始时初始化

    • 请求/会话结束时销毁

    • 完整的生命周期回调

四、最佳实践

  1. 尽量使用singleton作用域:性能最佳,适用于无状态服务

  2. 谨慎使用prototype:仅在必要时使用,注意资源释放

  3. 合理使用生命周期回调:资源初始化/释放放在合适的回调中

  4. 避免在singleton中注入prototype:会导致prototype失去意义,可以使用方法注入解决

  5. Web作用域Bean不要注入singleton:会导致状态不一致

五、总结

理解Spring Bean的生命周期和作用域对于开发高质量的Spring应用至关重要。通过合理利用生命周期回调和选择适当的作用域,可以构建出既高效又可靠的应用程序。记住,大多数情况下默认的singleton作用域是最佳选择,只有在确实需要时才使用其他作用域。

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

相关文章:

  • Vue-17-前端框架Vue之应用基础集中式状态管理pinia(二)
  • AI智能体在用户行为数据分析中有哪些应用?
  • Android 网络全栈攻略(四)—— TCPIP 协议族与 HTTPS 协议
  • Linux基本命令篇 —— grep命令
  • 基于ApachePOI实现百度POI分类快速导入PostgreSQL数据库实战
  • opencv使用 GStreamer 硬解码和 CUDA 加速的方案
  • 【cesium】基于vue-cesium开发地理空间分析应用
  • 在 Vue 3 中,如果需要显示 HTML 标签,可以使用 v-html 指令
  • android stdio 创建 mediaplayertest
  • 零信任安全管理系统产品对比介绍
  • 小米YU7使用UWB技术,厘米级定位精准迎宾,安全防破解无感控车
  • .NET测试工具Parasoft dotTEST:全兼容RMS的测试解决方案
  • 538. 把二叉搜索树转换为累加树
  • 清理 Docker 缓存占用
  • Vue 3.x 使用 “prerender-spa-plugin ” 预渲染实现网站 SEO 优化
  • 透视变换、仿射变换
  • webpack的作用是什么,谈谈你对它的理解?
  • MySQL索引失效问题
  • vue-35(使用 Jest 和 Vue Test Utils 设置测试环境)
  • 折扣点餐对接api应该如何选择?
  • React Native 0.79.4 中 [RCTView setColor:] 崩溃问题完整解决方案
  • 在线租房平台源码+springboot+vue3(前后端分离)
  • 模型部署与推理--利用python版本onnxruntime模型部署与推理
  • C++面试题精讲系列之数组排序
  • raid的介绍和raid对比 和 lvm 的介绍和使用 扩容
  • Qt 实现Opencv功能模块切换界面功能
  • 线性规划模型
  • 【V5.0 - 视觉篇】AI的“火眼金睛”:用OpenCV量化“第一眼缘”,并用SHAP验证它的“审美”
  • TensorFlow内核剖析:分布式TensorFlow架构解析与实战指南
  • 通往物理世界自主智能的二元实在论与罗塞塔协议