Spring框架中Bean的默认作用域是singleton(单例),即容器中同名Bean仅创建一个实例,所有获取请求均返回同一对象,适用于无状态的Service、DAO等组件,可提升性能并减少资源开销。

Spring 框架中 Bean 的默认作用域是 singleton(单例)。也就是说,只要不显式指定其他作用域,Spring 容器中同名 Bean 只会创建一个实例,所有获取请求都返回同一个对象。
为什么默认是 singleton?
单例模式能显著减少对象创建开销,提升性能,特别适合无状态的组件——比如 Service、DAO、Controller、配置类等。这些类通常不保存线程或请求相关的数据,可以安全共享。
- 容器启动时初始化(懒加载除外),关闭时销毁
- 无论用
@Autowired、context.getBean()还是不同客户端调用,拿到的都是同一实例 - 修改其中一个引用的属性,其他地方看到的也会变(注意有状态场景下的副作用)
如何修改 Bean 的作用域?
通过 @Scope 注解设置,支持字符串字面量或常量引用,推荐使用常量更安全:
-
@Scope("prototype")或@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE):每次获取都新建实例 -
@Scope("request")/"session"/"application"/"websocket":仅 Web 环境有效,需确保应用是 Web 类型(如引入spring-web) - XML 配置方式:
<bean scope="prototype" />
注解可加在 @Component、@Service 等类上,也可加在 @Bean 方法上。例如:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
@Service
@Scope("prototype")
public class ShoppingCart { ... }
修改作用域要注意什么?
作用域不是“设了就完事”,关键细节会影响实际行为:
-
prototypeBean 被注入到singletonBean 中时,注入动作只发生一次——结果仍是固定的一个实例。需改用ObjectProvider<T>或方法注入(@Lookup)动态获取新实例 -
request、session等 Web 作用域,在非 Web 环境(如纯单元测试或普通 Java 应用)中会抛出异常 - 自定义作用域需注册
Scope实现,并通过ConfigurableBeanFactory.registerScope()注册
验证作用域是否生效
最直接的方式是打印对象哈希值或内存地址:
Object a = context.getBean("myBean");
Object b = context.getBean("myBean");
System.out.println(a == b); // singleton 返回 true;prototype 返回 false
也可以配合日志或断点观察构造函数是否被多次调用。

















