【Spring】Spring 中的 Beans

Posted by 西维蜀黍 on 2025-07-21, Last Modified on 2025-07-22

Bean 是单例吗?

Spring 中的 Bean 默认都是单例的。

也就是说,每个 Bean 的实例只会被创建一次,并且会被存储在 Spring 容器的缓存中,以便在后续的请求中重复使用。

这种单例模式可以提高应用程序的性能和内存效率。

但是,Spring 也支持将 Bean 设置为多例模式,即每次请求都会创建一个新的 Bean 实例。

要将 Bean 设置为多例模式,可以在 Bean 定义中通过设置 scope 属性为 “prototype” 来实现。

需要注意的是,虽然 Spring 的默认行为是将 Bean 设置为单例模式,但在一些情况下,使用多例模式是更为合适的,例如在创建状态不可变的 Bean 或有状态的 Bean 时。

此外,需要注意的是,如果 Bean 单例是有状态的,那么在使用时需要考虑线程安全性问题。

Bean 的单例和非单例,生命周期是否一样?

不一样的,Spring Bean 的生命周期完全由 IoC 容器控制。

Spring 只帮我们管理单例模式 Bean 的完整生命周期。

对于 prototype 的 Bean,Spring 在创建好交给使用者之后,则不会再管理后续的生命周期。

具体区别如下:

阶段 单例(Singleton) 非单例(如 Prototype)
创建时机 容器启动时创建(或首次请求时,取决于配置) 每次请求时创建新实例
初始化流程 完整执行生命周期流程(属性注入、Aware 接口、初始化方法等) 每次创建新实例时都会完整执行生命周期流程(仅初始化阶段)
销毁时机 容器关闭时销毁,触发 DisposableBean 或 destroy-method 容器不管理销毁,需由用户自行释放资源(Spring 不跟踪实例)
内存占用 单实例维护在内存中,高效但需注意线程安全 每次请求生成新实例,内存开销较大,需手动管理资源释放
适用场景 无状态服务(如 Service、DAO 层) 有状态对象(如用户会话、临时计算对象)

Spring Bean 的作用域有哪些?

Spring 框架中的 Bean 作用域(Scope)定义了 Bean 的生命周期和可见性。不同的作用域影响着 Spring 容器如何管理这些 Bean 的实例,包括它们如何被创建、如何被销毁以及它们是否可以被多个对象共享。

✅ Spring 支持的作用域类型:

Scope 类型 描述
Singleton(单例) 默认作用域。在整个应用程序中只存在一个 Bean 实例,Spring 容器中会创建并缓存一个实例,所有请求共享。
Prototype(原型) 每次请求都会创建一个新的 Bean 实例,不进行缓存。适用于有状态或临时性的 Bean。
Request(请求) 每个 HTTP 请求会创建一个新的 Bean 实例。仅适用于 Spring Web 应用
Session(会话) 每个 HTTP Session 创建一个新的 Bean 实例,适用于有用户状态的 Web 应用场景
Application 当前 ServletContext 范围内只存在一个 Bean 实例,整个 Web 应用共享。
WebSocket WebSocket 范围内的共享 Bean,仅在支持 WebSocket 的 Spring 应用中有效。
Custom scopes(自定义作用域) 开发者可以通过实现 Scope 接口创建自定义作用域逻辑。

基于注解配置(Spring Boot 推荐):

@Bean
@Scope("prototype")
public MyBeanClass myBean() {
    return new MyBeanClass();
}

Reference