昨天的面试让我对 Spring Boot 的核心注解有了更深的理解,复盘时不仅完善了 @SpringBootConfiguration
的定制和 @EnableAutoConfiguration
的条件注解细节,还想到一个相关但没被问到的知识点:Bean 的作用域(Scope)。在 Spring 中,Bean 的作用域决定了它的生命周期和实例化方式,这对理解 Spring 容器管理非常重要。面试官虽然没问,但我复盘时觉得这是个高频考点,值得整理一下,算是给自己加个"隐藏分"。
前文回顾(略)
之前已经聊了 @SpringBootApplication
的三个子注解:@SpringBootConfiguration
(定制化配置)、@EnableAutoConfiguration
(自动配置与条件注解)、@ComponentScan
(组件扫描)。这些注解共同管理了 Bean 的创建和注入,而 Bean 的作用域则是另一个关键维度。下面就详细说说。
Bean 的 Scope 作用域及其范围
在 Spring 中,Bean 的作用域通过 @Scope
注解定义,默认是 singleton
。但 Spring 提供了多种作用域,适用于不同场景。以下是常见的 Scope 类型及其范围:
-
singleton
(单例)- 作用:整个应用中只有一个实例,所有对该 Bean 的引用都指向同一个对象。
- 范围:Spring 容器全局唯一,Bean 在容器启动时创建,销毁时释放。
- 使用场景 :无状态的服务类或工具类,比如
UserService
,适合共享使用。 - 细节 :可以通过
@Scope("singleton")
显式指定,但默认就是这个,所以很少写。
-
prototype
(原型)- 作用:每次请求该 Bean 时,都会创建一个新实例。
- 范围 :每次注入或通过
getBean
获取时独立创建,生命周期由调用方管理(Spring 不负责销毁)。 - 使用场景 :有状态的对象,比如每次请求需要独立数据的
UserContext
。 - 细节 :用
@Scope("prototype")
指定。复盘时想到,如果面试官问"prototype 的销毁怎么办",可以回答"Spring 不管,需要开发者手动清理或交给垃圾回收"。
-
request
(请求)- 作用:每个 HTTP 请求创建一个独立实例,请求结束后销毁。
- 范围:仅限于 Web 应用,绑定到单个 HTTP 请求的生命周期。
- 使用场景:Web 开发中需要请求隔离的数据,比如当前请求的用户信息。
- 细节 :需要引入
spring-web
依赖,用@Scope("request")
指定。
-
session
(会话)- 作用:每个 HTTP 会话创建一个独立实例,会话结束后销毁。
- 范围:Web 应用的会话级别,通常跨多个请求。
- 使用场景:用户的登录状态或购物车数据。
- 细节 :同样需要 Web 环境支持,用
@Scope("session")
。
-
application
(应用)- 作用 :整个 Web 应用中只有一个实例,类似于
singleton
,但绑定到 Servlet 上下文。 - 范围:ServletContext 的生命周期,通常在 Web 容器启动时创建。
- 使用场景:全局配置或计数器。
- 细节 :用
@Scope("application")
,比singleton
更明确地表示 Web 应用级别。
- 作用 :整个 Web 应用中只有一个实例,类似于
-
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 场景下用哪个",我可以自信地说"request
或 session
,看需求隔离级别"。
复盘时还想到一个小细节:singleton
和 application
的区别容易混淆,前者是 Spring 容器级别,后者是 Servlet 上下文级别,Web 项目中可能有细微差异。
总结
加上 Bean 的作用域,这次复盘更全面了。@SpringBootApplication
通过子注解管理 Bean 的创建,而 Scope 决定了 Bean 的生命周期和实例化范围。常见的作用域包括:
singleton
:全局单例,默认。prototype
:每次新实例。- Web 专属:
request
、session
、application
。
下次面试如果遇到类似问题,我会更有底气,甚至可以主动抛出"Bean 的作用域您想让我展开吗?"这样的反问,争取多展示一些知识面。这次复盘让我对 Spring 的掌控感又提升了一步!