为什么 Spring 强烈推荐你用 singleton

27 阅读3分钟

在 Spring 项目里,有一个几乎“隐形”的事实:

你几乎没显式写过 @Scope("singleton")
但你每天都在用 singleton。

这不是巧合,而是 Spring Framework 的刻意设计

那问题来了:

👉 Spring 为什么要“强烈推荐”你用 singleton?
👉 prototype 明明更自由,为什么反而不常用?

一、先给结论(不卖关子)

Spring 推荐 singleton,不是因为它“简单”,而是因为:

singleton 和现代服务端架构,是天然契合的。

后面所有理由,其实都围绕这句话展开。

二、原因一:服务端应用,本质就是“无状态”的

我们先抛开 Spring,看一眼现实世界里的服务端系统。

你每天写的 Service,通常在干嘛?

  • 接收参数
  • 查询数据库
  • 计算结果
  • 返回响应

换句话说:

一次请求结束,Service 本身不应该“记住任何东西”。

这种对象,有一个标准名称:

无状态对象(Stateless Object)

singleton + 无状态 = 完美搭档

  • singleton:全局只有一个实例
  • 无状态:内部没有可变数据

👉 合在一起的结果是:

  • 没有并发问题
  • 可以被无限复用
  • 非常省资源

这正是 Spring 默认选择 singleton 的第一性原因。

三、原因二:对象创建,其实比你想象的“贵”

很多人会低估 new 一个对象的成本。

但在真实项目中,一个 Bean 往往伴随着:

Bean ≠ 普通的 POJO new

prototype 的真实代价

如果你大量使用 prototype:

  • 每次获取都要创建对象
  • 每次都要重新走初始化流程
  • GC 压力明显增加

而 singleton:

  • 初始化一次
  • 后续只用引用
  • JVM 和 GC 都很开心

👉 Spring 选择 singleton,是一个典型的性能优先决策。

四、原因三:容器才能“真正管理” singleton

这是一个非常关键但经常被忽略的点

Spring 对 singleton 能做什么?

  • 完整生命周期管理
  • AOP 代理(事务、日志、权限)
  • 循环依赖处理
  • 统一销毁

而 prototype 呢?

Spring 只负责创建,不负责销毁。

这意味着:

  • 资源释放要你自己管
  • 生命周期不完整
  • 很难统一治理

从框架设计角度看

只有 singleton,才是 Spring 真正“掌控得住”的 Bean。

这也是为什么:

  • 大量 Spring 特性是围绕 singleton 设计的
  • prototype 更像是“高级用法”,而不是默认选项

五、原因四:大部分“状态”,其实不该放在 Bean 里

这是很多 singleton “翻车”的根源。

错误的直觉

“我这个逻辑有状态,那我就用 prototype 吧。”

但真实世界里,状态通常应该放在:

  • 方法参数
  • 返回对象
  • ThreadLocal
  • 外部存储(DB / Redis)

而不是:

  • Bean 的成员变量

一个重要的分界线

Bean = 行为
State = 数据

当你把这两件事分开看时,会发现:

  • 绝大多数 Bean 都天然适合 singleton
  • prototype 的使用场景其实非常少

六、原因五:singleton 是“安全默认值”

从框架设计者视角看:

  • 新手用户居多
  • 错误用法比正确用法更常见

如果 Spring 默认是 prototype,会发生什么?

  • 内存暴涨
  • 性能抖动
  • 生命周期失控
  • 问题极难排查

而 singleton:

  • 行为稳定
  • 成本可控
  • 出问题也更容易定位

👉 singleton 是一个“不容易把系统拖死”的默认值。

七、那 prototype 真的没用吗?

不是。

但它适合的场景非常明确:

  • 明确的、有状态对象
  • 短生命周期
  • 清楚地知道“为什么不能用 singleton”

如果你需要反复问:

“这个地方是不是该用 prototype?”

那答案往往是:

不该。

八、总结一句话(可以直接当结尾)

Spring 强烈推荐 singleton,不是因为它保守,而是因为它看清了现实:

大多数服务端对象,本就该是无状态、可复用、易管理的。

最后送你一句“写在墙上的话”:

当你犹豫一个 Bean 用什么 Scope 时,请先假设它是 singleton,直到你能明确说出“为什么不是”。