16. Spring Bean 一共有几种作用域?
在 Spring 框架中,Bean 作用域(Scope)定义了 Spring 容器如何创建、管理和缓存 Bean 实例。Spring 默认提供了几种常见的 Bean 作用域,每种作用域的管理方式不同,适用于不同的应用场景。以下是 Spring 中主要的几种作用域:
1. singleton
描述:这是 Spring 的默认作用域。在
singleton
作用域下,Spring 容器中每个 Bean 定义对应一个唯一的实例,无论多少次请求该 Bean,都会返回同一个实例。应用场景:适用于无状态的 Bean 或者希望在整个应用程序中共享同一个实例的情况。
示例:
@Bean @Scope("singleton") public MyService myService() { return new MyServiceImpl(); }
在上面的例子中,
myService
Bean 在整个 Spring 容器中只有一个实例。
2. prototype
描述:在
prototype
作用域下,每次请求该 Bean 时,Spring 容器都会创建一个新的实例。应用场景:适用于有状态的 Bean,或者在每次使用时都需要一个全新实例的情况。
示例:
@Bean @Scope("prototype") public MyService myService() { return new MyServiceImpl(); }
在这种情况下,每次注入
myService
时,都会得到一个新的实例。
3. request
描述:在 Web 应用中,
request
作用域会为每个 HTTP 请求创建一个 Bean 实例,并且该实例只在当前请求内有效。当请求结束时,Bean 将会被销毁。应用场景:适用于需要在每个 HTTP 请求中保持独立状态的 Bean。
示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public MyService myService() { return new MyServiceImpl(); }
每个请求都会获得一个独立的
myService
实例。
4. session
描述:在 Web 应用中,
session
作用域会为每个 HTTP 会话创建一个 Bean 实例,并且该实例在会话范围内共享。当会话结束时,Bean 将被销毁。应用场景:适用于在用户会话期间需要保持状态的 Bean。
示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public MyService myService() { return new MyServiceImpl(); }
同一个用户的会话内,
myService
实例是相同的,但不同会话有不同的实例。
5. globalSession
描述:
globalSession
作用域与session
类似,但它通常用于基于 Portlet 的 Web 应用程序,提供全局的 Portlet 会话作用域。应用场景:主要用于 Portlet 环境,在标准的 Web 应用中较少使用。
示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_GLOBAL_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public MyService myService() { return new MyServiceImpl(); }
每个 Portlet 全局会话共享一个 Bean 实例。
6. application
描述:
application
作用域表示在整个 ServletContext 生命周期内,Bean 是单例的,所有的请求和会话共享同一个 Bean 实例。应用场景:适用于整个应用范围内共享状态的 Bean。
示例:
@Bean @Scope(value = WebApplicationContext.SCOPE_APPLICATION) public MyService myService() { return new MyServiceImpl(); }
在整个 Web 应用的生命周期中,
myService
都是同一个实例。
总结
Spring 提供了多种作用域来满足不同场景下的需求,从单例模式的 singleton
到每次请求新建的 prototype
,再到与 Web 应用相关的 request
、session
和 globalSession
作用域。了解这些作用域的特性并根据实际情况选择合适的作用域,可以更好地管理应用中的 Bean 生命周期和状态。