通俗易懂!2025 年最新 Spring Bean 作用域全家福(面试画图+口诀,背完直接秒)
| 作用域 | 数量 | 什么时候创建 | 典型使用场景 | 2025 项目真实使用频率 | 面试口诀记忆法 |
|---|---|---|---|---|---|
| singleton ★★★★★ | 整个容器就1个 | 容器启动时立刻创建(默认) | Service、Mapper、Controller、Config… | 99.9% | “单身狗”:一辈子就谈一次恋爱 |
| prototype | 每次要都给你造一个新的 | getBean() 的时候才创建 | 需要每次都是新对象:实体类、DTO、某些工具 | 0.05% | “多情种”:每次 getBean 都换新欢 |
| request | 每个 HTTP 请求1个 | 请求进来才创建,请求结束就销毁 | 需要存放当前请求数据的对象 | ★★★(Web 项目常用) | “一夜情”:一个请求谈一次恋爱 |
| session | 每个 HttpSession 1个 | 登录后创建,登出/过期销毁 | 存放登录用户信息 | ★★★ | “谈恋爱”:一个用户谈一次 |
| application | 整个 Web 应用就1个 | 应用启动时创建,应用关闭销毁 | 全局配置、统计数据 | ★ | “结婚”:一辈子就一次 |
| websocket | 每个 WebSocket 会话1个 | WebSocket 连接建立时创建 | 聊天室、实时推送 | ★(小众) | “网恋”:一个连接谈一次 |
2025 年真实项目用法(直接抄)
@Service // 默认就是 singleton(不用写)
public class UserService { }
@Component
@Scope("prototype") // 每次都要新的
public class IdGenerator { }
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestContext { } // 关键!不加 proxyMode 会报错
@Component
@Scope("session")
public class LoginUserHolder { } // 存放当前登录用户
重磅提醒:request/session 作用域必须加代理!(90%的人栽这里)
错的写法(启动就报错):
@Scope("request")
@Component
public class RequestHolder { } // 报错!singleton 里注入了 request 作用域
正确写法(加代理,面试必写):
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestHolder { }
@Service
public class OrderService {
@Autowired
private RequestHolder holder; // 注入的是代理对象,真正使用时才去拿当前请求的实例
}
面试终极 6 连问 + 标准答案(背完无敌)
- Spring 默认作用域是什么?
→ singleton,容器启动就造好一个,全球共享。 - prototype Bean 什么时候创建?
→ 每次调用 getBean() 才创建,容器不缓存。 - request/session 作用域在非 Web 环境能用吗?
→ 不能!启动直接报错。 - singleton Bean 里能注入 prototype Bean 吗?
→ 直接注入不行!会永远拿到第一次那个实例。
解决方案:① 用 @Lookup 方法注入(推荐) ② 加 ObjectFactory/Provider ③ 加 proxyMode - 经典解法(直接背代码):
@Service
public class OrderService {
// 方式1:@Lookup(最优雅)
@Lookup
public PrototypeBean getProto() { return null; }
// 方式2:注入 Provider
@Autowired
private Provider<PrototypeBean> protoProvider;
public void test() {
PrototypeBean bean = protoProvider.get(); // 每次都是新的!
}
}
- 5 种作用域怎么配置?
→ @Scope(“xxx”),request/session 必须加 proxyMode = ScopedProxyMode.TARGET_CLASS
终极口诀(10 秒记住全部)
“singleton 单身狗,全局就一个我
prototype 多情种,每次都换新
request 一夜情,一个请求谈一次
session 谈恋爱,一个用户谈一次
application 结婚,应用里就一个”
背完这张表 + 口诀 + 代理写法,
面试官让你“讲讲 Spring Bean 的作用域”,你 1 分钟画表 + 甩代码 + 背口诀,直接满分!
现在连大厂面试官都会说:“这个小伙子作用域讲得比我还清楚!”冲!