题目
Spring Bean 的作用域有哪些?默认作用域是什么?如何配置作用域?
信息
- 类型:问答
- 难度:⭐
考点
Bean作用域,依赖注入基础,配置方式
快速回答
Spring Bean 的常见作用域包括:
- singleton(默认):每个 Spring 容器中只有一个实例
- prototype:每次请求都创建新实例
- request:每个 HTTP 请求创建一个实例
- session:每个 HTTP 会话创建一个实例
- application:每个 ServletContext 生命周期一个实例
配置方式:
- XML:
<bean scope="prototype"> - 注解:
@Scope("prototype")
一、作用域类型详解
Spring 管理 Bean 的生命周期范围:
- singleton(默认):容器初始化时创建单个实例,所有依赖注入共享同一对象
- prototype:每次通过容器获取 Bean 时都创建新实例
- request:Web 环境中,每个 HTTP 请求创建新实例
- session:Web 环境中,每个用户会话创建新实例
- application:Web 环境中,整个 Web 应用共享一个实例
二、配置方式示例
1. XML 配置
<!-- 显式声明 singleton(可省略) -->
<bean id="userService" class="com.example.UserService" scope="singleton"/>
<!-- 配置 prototype 作用域 -->
<bean id="reportGenerator" class="com.example.ReportGenerator" scope="prototype"/>2. 注解配置
// 在类上使用注解
@Component
@Scope("prototype") // 或 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ReportGenerator { ... }
// Java Config 配置
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public ReportGenerator reportGenerator() {
return new ReportGenerator();
}
}三、最佳实践与注意事项
- 无状态 Bean 用 singleton:线程安全的工具类服务推荐使用单例(节省资源)
- 有状态 Bean 用 prototype:需要维护成员变量的对象(如购物车)
- Web 作用域需配置监听器:使用 request/session 作用域时,需在 web.xml 添加:
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
四、常见错误
- 单例中误用原型:在 singleton Bean 中直接注入 prototype Bean 会导致原型失效(始终使用同一实例)
- 解决方案:通过方法注入或
@Lookup注解获取新实例 - 作用域混淆:在非 Web 环境使用 request/session 作用域会抛出
IllegalStateException
五、扩展知识
- 自定义作用域:实现
Scope接口可创建自定义作用域(如线程作用域) - 作用域代理模式:
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)解决单例引用短作用域 Bean 的问题 - 性能影响:prototype 作用域频繁创建实例可能增加 GC 压力,需评估必要性