Spring Boot 的Scope:Singleton/Prototype/Request/Session/Application/WebSocket


昨天的面试让我对 Spring Boot 的核心注解有了更深的理解,复盘时不仅完善了 @SpringBootConfiguration 的定制和 @EnableAutoConfiguration 的条件注解细节,还想到一个相关但没被问到的知识点:Bean 的作用域(Scope)。在 Spring 中,Bean 的作用域决定了它的生命周期和实例化方式,这对理解 Spring 容器管理非常重要。面试官虽然没问,但我复盘时觉得这是个高频考点,值得整理一下,算是给自己加个"隐藏分"。

前文回顾(略)

之前已经聊了 @SpringBootApplication 的三个子注解:@SpringBootConfiguration(定制化配置)、@EnableAutoConfiguration(自动配置与条件注解)、@ComponentScan(组件扫描)。这些注解共同管理了 Bean 的创建和注入,而 Bean 的作用域则是另一个关键维度。下面就详细说说。

Bean 的 Scope 作用域及其范围

在 Spring 中,Bean 的作用域通过 @Scope 注解定义,默认是 singleton。但 Spring 提供了多种作用域,适用于不同场景。以下是常见的 Scope 类型及其范围:

  1. singleton(单例)

    • 作用:整个应用中只有一个实例,所有对该 Bean 的引用都指向同一个对象。
    • 范围:Spring 容器全局唯一,Bean 在容器启动时创建,销毁时释放。
    • 使用场景 :无状态的服务类或工具类,比如 UserService,适合共享使用。
    • 细节 :可以通过 @Scope("singleton") 显式指定,但默认就是这个,所以很少写。
  2. prototype(原型)

    • 作用:每次请求该 Bean 时,都会创建一个新实例。
    • 范围 :每次注入或通过 getBean 获取时独立创建,生命周期由调用方管理(Spring 不负责销毁)。
    • 使用场景 :有状态的对象,比如每次请求需要独立数据的 UserContext
    • 细节 :用 @Scope("prototype") 指定。复盘时想到,如果面试官问"prototype 的销毁怎么办",可以回答"Spring 不管,需要开发者手动清理或交给垃圾回收"。
  3. request(请求)

    • 作用:每个 HTTP 请求创建一个独立实例,请求结束后销毁。
    • 范围:仅限于 Web 应用,绑定到单个 HTTP 请求的生命周期。
    • 使用场景:Web 开发中需要请求隔离的数据,比如当前请求的用户信息。
    • 细节 :需要引入 spring-web 依赖,用 @Scope("request") 指定。
  4. session(会话)

    • 作用:每个 HTTP 会话创建一个独立实例,会话结束后销毁。
    • 范围:Web 应用的会话级别,通常跨多个请求。
    • 使用场景:用户的登录状态或购物车数据。
    • 细节 :同样需要 Web 环境支持,用 @Scope("session")
  5. application(应用)

    • 作用 :整个 Web 应用中只有一个实例,类似于 singleton,但绑定到 Servlet 上下文。
    • 范围:ServletContext 的生命周期,通常在 Web 容器启动时创建。
    • 使用场景:全局配置或计数器。
    • 细节 :用 @Scope("application"),比 singleton 更明确地表示 Web 应用级别。
  6. websocket(WebSocket)(Spring 4.1+)

    • 作用:每个 WebSocket 会话创建一个实例。
    • 范围:绑定到 WebSocket 连接的生命周期。
    • 使用场景:实时通信场景,比如聊天应用。
    • 细节 :用 @Scope("websocket"),比较小众,但可能是个加分点。

配置方式

在 Spring Boot 中,定义 Bean 的作用域通常有两种方式:

  • 注解方式 :在 @Bean@Component 上加 @Scope,比如:

    java 复制代码
    @Bean
    @Scope("prototype")
    public UserContext userContext() {
        return new UserContext();
    }
  • XML 方式 :老项目可能用 <bean scope="prototype">,但 Spring Boot 基本不用了。

复盘感想

Bean 的作用域虽然这次没被问到,但它是 Spring 核心知识的一部分,跟 @SpringBootConfiguration 定义 Bean 的过程息息相关。如果面试官追问"单例和原型的区别",我可以回答:"单例是全局共享,原型是每次独立创建,适合有状态对象。"如果再问"Web 场景下用哪个",我可以自信地说"requestsession,看需求隔离级别"。

复盘时还想到一个小细节:singletonapplication 的区别容易混淆,前者是 Spring 容器级别,后者是 Servlet 上下文级别,Web 项目中可能有细微差异。

总结

加上 Bean 的作用域,这次复盘更全面了。@SpringBootApplication 通过子注解管理 Bean 的创建,而 Scope 决定了 Bean 的生命周期和实例化范围。常见的作用域包括:

  • singleton:全局单例,默认。
  • prototype:每次新实例。
  • Web 专属:requestsessionapplication

下次面试如果遇到类似问题,我会更有底气,甚至可以主动抛出"Bean 的作用域您想让我展开吗?"这样的反问,争取多展示一些知识面。这次复盘让我对 Spring 的掌控感又提升了一步!

相关推荐
追逐时光者1 小时前
分享一个纯净无广、原版操作系统、开发人员工具、服务器等资源免费下载的网站
后端·github
JavaPub-rodert2 小时前
golang 的 goroutine 和 channel
开发语言·后端·golang
ivygeek3 小时前
MCP:基于 Spring AI Mcp 实现 webmvc/webflux sse Mcp Server
spring boot·后端·mcp
GoGeekBaird4 小时前
69天探索操作系统-第54天:嵌入式操作系统内核设计 - 最小内核实现
后端·操作系统
鱼樱前端4 小时前
Java Jdbc相关知识点汇总
java·后端
canonical_entropy5 小时前
NopReport示例-动态Sheet和动态列
java·后端·excel
kkk哥5 小时前
基于springboot的母婴商城系统(018)
java·spring boot·后端
Asthenia04126 小时前
面试复盘:关于 Redis 如何实现分布式锁
后端
Asthenia04126 小时前
如何修改 MySQL 的数据库隔离级别:命令global、session/my.cnf中修改
后端