Spring 中的 bean 作用域
在 Spring 中,bean
的作用域(Scope)定义了 bean
的生命周期和可见范围。Spring 主要提供了以下几种作用域:
1. singleton(默认作用域)
- 描述:每个 Spring 容器中,
bean
只有一个实例,所有对该bean
的请求都会返回同一个实例。 - 适用场景:大多数
bean
适用于singleton
,如Service
、Repository
等无状态的bean
。 - 示例:
@Bean @Scope("singleton") // 也可以不写,默认就是 singleton public MyBean myBean() { return new MyBean(); }
2. prototype
- 描述:每次获取
bean
时,都会创建一个新的实例。 - 适用场景:适用于有状态的
bean
,如带有用户会话信息的bean
。 - 示例:
@Bean @Scope("prototype") public MyBean myBean() { return new MyBean(); }
- 注意:
prototype
作用域的bean
由 Spring 负责创建,但不负责管理其生命周期(例如不会自动销毁)。- 需要手动管理
bean
的销毁,比如使用@PreDestroy
方法不会被 Spring 调用。
3. request(仅适用于 Web 应用)
- 描述:每个 HTTP 请求都会创建一个新的
bean
实例,请求结束后bean
被销毁。 - 适用场景:适用于需要在请求范围内保存状态的
bean
,如Controller
层的bean
。 - 示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public MyBean myBean() { return new MyBean(); }
- 注意:
- 需要在 Spring Web 环境下使用,否则会抛出异常。
4. session(仅适用于 Web 应用)
- 描述:每个 HTTP 会话(Session)都会创建一个
bean
实例,Session 结束后bean
被销毁。 - 适用场景:适用于需要在整个用户会话期间保存状态的
bean
。 - 示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public MyBean myBean() { return new MyBean(); }
5. application(仅适用于 Web 应用)
- 描述:
bean
的生命周期与ServletContext
相同,即整个应用共享一个实例。 - 适用场景:适用于全局配置
bean
,如应用级别的Cache
。 - 示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_APPLICATION) public MyBean myBean() { return new MyBean(); }
6. websocket(仅适用于 WebSocket 应用)
- 描述:每个 WebSocket 连接都会创建一个
bean
实例,连接关闭后bean
被销毁。 - 适用场景:适用于 WebSocket 连接的会话管理。
- 示例:
@Bean @Scope(value = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS) public MyBean myBean() { return new MyBean(); }
如何选择合适的作用域?
作用域 | 适用场景 |
---|---|
singleton | 无状态的、共享的 bean (默认值) |
prototype | 需要每次创建新实例的 bean |
request | 仅在一次 HTTP 请求中存活的 bean |
session | 需要在整个会话期间存活的 bean |
application | 需要在整个 Web 应用生命周期内共享的 bean |
websocket | 需要在 WebSocket 连接期间存活的 bean |
一般情况下,推荐使用 singleton
作用域,只有在特殊需求(如用户会话、线程安全等)时才考虑其他作用域。