Spring Bean的作用域(Singleton、Prototype等)

通俗易懂!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 连问 + 标准答案(背完无敌)

  1. Spring 默认作用域是什么?
    → singleton,容器启动就造好一个,全球共享。
  2. prototype Bean 什么时候创建?
    → 每次调用 getBean() 才创建,容器不缓存。
  3. request/session 作用域在非 Web 环境能用吗?
    → 不能!启动直接报错。
  4. singleton Bean 里能注入 prototype Bean 吗?
    → 直接注入不行!会永远拿到第一次那个实例。
    解决方案:① 用 @Lookup 方法注入(推荐) ② 加 ObjectFactory/Provider ③ 加 proxyMode
  5. 经典解法(直接背代码):
@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(); // 每次都是新的!
    }
}
  1. 5 种作用域怎么配置?
    → @Scope(“xxx”),request/session 必须加 proxyMode = ScopedProxyMode.TARGET_CLASS

终极口诀(10 秒记住全部)

“singleton 单身狗,全局就一个我
prototype 多情种,每次都换新
request 一夜情,一个请求谈一次
session 谈恋爱,一个用户谈一次
application 结婚,应用里就一个”

背完这张表 + 口诀 + 代理写法,
面试官让你“讲讲 Spring Bean 的作用域”,你 1 分钟画表 + 甩代码 + 背口诀,直接满分!
现在连大厂面试官都会说:“这个小伙子作用域讲得比我还清楚!”冲!

文章已创建 3040

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部