在 Spring 中,Bean 的作用域定义了 Bean 在 Spring 容器中的生命周期和可见范围。Spring 提供了多种 Bean 作用域,以下是常见的几种及其适用场景:
1. singleton
(单例作用域)
- 描述:这是 Spring 默认的 Bean 作用域。在整个 Spring 容器的生命周期内,对于一个
singleton
作用域的 Bean,Spring 容器只会创建一个实例,并且所有对该 Bean 的请求都会返回同一个实例。 - 适用场景
- 无状态的 Bean:例如服务层的业务逻辑类,这些类通常不保存特定于某个请求或用户的状态信息,只包含一些通用的业务处理方法。如用户服务类
UserService
,它可能包含用户注册、登录等通用业务逻辑,不需要为每个请求都创建一个新的实例。 - 配置信息类:像数据库连接配置类、系统参数配置类等,这些类的配置信息在整个应用程序中是共享的,只需要一个实例即可。
- 无状态的 Bean:例如服务层的业务逻辑类,这些类通常不保存特定于某个请求或用户的状态信息,只包含一些通用的业务处理方法。如用户服务类
2. prototype
(原型作用域)
- 描述:每次从 Spring 容器中获取
prototype
作用域的 Bean 时,容器都会创建一个新的实例。也就是说,对该 Bean 的每个请求都会返回一个不同的实例。 - 适用场景
- 有状态的 Bean:当 Bean 需要保存特定于某个请求或用户的状态信息时,使用
prototype
作用域比较合适。例如,购物车类ShoppingCart
,每个用户的购物车内容是不同的,因此需要为每个用户创建一个独立的购物车实例。 - 多线程环境下需要避免共享状态的 Bean:在多线程应用中,如果一个 Bean 的状态可能会被多个线程同时访问和修改,为了避免线程安全问题,可以将其设置为
prototype
作用域,确保每个线程都使用自己的 Bean 实例。
- 有状态的 Bean:当 Bean 需要保存特定于某个请求或用户的状态信息时,使用
3. request
(请求作用域,仅适用于 Web 应用)
- 描述:在一次 HTTP 请求的生命周期内,Spring 容器会为
request
作用域的 Bean 创建一个实例。对于同一个请求中的所有对该 Bean 的引用,都会返回同一个实例;而不同的请求会得到不同的实例。 - 适用场景
- 处理请求相关信息的 Bean:例如处理用户请求参数的 Bean,它可能会根据当前请求的参数进行一些处理和计算,不同的请求可能会有不同的参数,因此需要为每个请求创建一个独立的实例。
- 记录请求日志的 Bean:在处理每个请求时,需要记录该请求的相关信息,如请求的 URL、请求时间等,使用
request
作用域可以确保每个请求的日志信息是独立记录的。
4. session
(会话作用域,仅适用于 Web 应用)
- 描述:在一个用户会话的生命周期内,Spring 容器会为
session
作用域的 Bean 创建一个实例。同一个用户的不同请求在同一个会话中会共享同一个 Bean 实例;而不同用户的会话会得到不同的实例。 - 适用场景
- 用户会话信息管理的 Bean:例如用户登录状态管理类,它可以保存用户的登录信息、权限信息等,在用户的整个会话期间都可以使用这些信息。
- 用户个性化设置的 Bean:如用户的主题设置、语言偏好等,这些信息在用户的会话期间是保持不变的,可以使用
session
作用域的 Bean 来管理。
5. application
(应用作用域,仅适用于 Web 应用)
- 描述:在整个 Web 应用程序的生命周期内,Spring 容器会为
application
作用域的 Bean 创建一个实例。所有用户的请求都会共享同一个 Bean 实例。 - 适用场景
- 统计应用程序全局信息的 Bean:例如统计网站的访问量、在线用户数等全局信息的 Bean,这些信息在整个应用程序中是共享的,只需要一个实例来进行统计和管理。
- 应用程序级别的配置信息管理 Bean:如应用程序的全局配置参数,这些参数在整个应用程序中是固定的,所有用户都可以访问和使用这些配置信息。
6. websocket
(WebSocket 作用域,仅适用于 Spring WebSocket 应用)
- 描述:在一个 WebSocket 会话的生命周期内,Spring 容器会为
websocket
作用域的 Bean 创建一个实例。同一个 WebSocket 会话中的所有消息处理都会共享同一个 Bean 实例;而不同的 WebSocket 会话会得到不同的实例。 - 适用场景
- 处理 WebSocket 会话相关信息的 Bean:例如管理 WebSocket 连接状态、处理 WebSocket 消息的 Bean,每个 WebSocket 会话都有自己独立的状态和消息处理逻辑,使用
websocket
作用域可以确保每个会话的信息和处理逻辑是独立的。
- 处理 WebSocket 会话相关信息的 Bean:例如管理 WebSocket 连接状态、处理 WebSocket 消息的 Bean,每个 WebSocket 会话都有自己独立的状态和消息处理逻辑,使用
示例代码
XML 配置方式
<bean id="singletonBean" class="com.example.SingletonBean" scope="singleton"/>
<bean id="prototypeBean" class="com.example.PrototypeBean" scope="prototype"/>
Java 注解方式
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class AppConfig {
@Bean
@Scope("singleton")
public SingletonBean singletonBean() {
return new SingletonBean();
}
@Bean
@Scope("prototype")
public PrototypeBean prototypeBean() {
return new PrototypeBean();
}
}