Spring Bean 的常见作用域(scope)

1. singleton(单例)

  • 默认作用域
  • 整个容器中只存在一个实例
  • 所有对该 Bean 的请求都返回同一个对象
  • 适用于无状态的服务类
@Component
@Scope("singleton")  // 可省略,默认就是 singleton
public class UserService {
    // ...
}

2. prototype(原型)

  • 每次请求都创建一个新的实例
  • 容器不管理 prototype Bean 的完整生命周期
  • 适用于有状态的对象
@Component
@Scope("prototype")
public class UserRequest {
    // ...
}

3. request(请求)

  • 仅限 Web 环境
  • 每个 HTTP 请求创建一个新实例
  • 请求结束后,Bean 被销毁
@Component
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class RequestData {
    // ...
}

4. session(会话)

  • 仅限 Web 环境
  • 每个 HTTP Session 创建一个新实例
  • Session 结束后,Bean 被销毁
@Component
@Scope(WebApplicationContext.SCOPE_SESSION)
public class UserSession {
    // ...
}

5. application(应用)

  • 仅限 Web 环境
  • 整个 ServletContext 生命周期内只有一个实例
  • 类似 singleton,但仅限于 Web 应用
@Component
@Scope(WebApplicationContext.SCOPE_APPLICATION)
public class AppConfig {
    // ...
}

6. websocket(WebSocket)

  • 仅限 WebSocket 环境
  • 每个 WebSocket 会话创建一个新实例
@Component
@Scope(WebApplicationContext.SCOPE_WEBSOCKET)
public class WebSocketHandler {
    // ...
}

默认作用域

默认是 singleton

@Component
public class MyBean {
    // 默认就是 singleton 作用域
}

作用域对比表

作用域 说明 适用环境 实例数量
singleton 单例,容器中唯一实例 所有环境 1
prototype 原型,每次请求创建新实例 所有环境 N
request 每个 HTTP 请求一个实例 Web 环境 N(每请求)
session 每个 HTTP Session 一个实例 Web 环境 N(每会话)
application 整个 Web 应用一个实例 Web 环境 1
websocket 每个 WebSocket 会话一个实例 WebSocket 环境 N(每连接)

注意事项

⚠️ 依赖注入问题

singleton Bean 依赖 prototype Bean 时,prototype Bean 只会在 singleton 初始化时创建一次,不会每次都创建新实例。

解决方案

  1. 使用 @Lookup 方法注入
  2. 使用 ObjectProviderProvider<T>
  3. 通过 ApplicationContext 手动获取
@Component
public class SingletonService {
    
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;
    
    public void doSomething() {
        // 每次调用获取新实例
        PrototypeBean bean = prototypeBeanProvider.getObject();
    }
}

⚠️ 线程安全

  • singleton Bean 需要保证线程安全(避免可变状态)
  • prototype Bean 天然线程安全(每个线程独立实例)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐