bean 作用域(scope) 控制容器创建多少个实例、它们存活多久。生命周期回调(lifecycle callbacks) 让你在一个 bean 刚构造完之后、以及即将被销毁之前运行代码。
你真正会用到的作用域
- singleton(默认):每个容器一个共享实例。在启动时被急切地创建。
@Service // 默认为 singleton —— 整个应用共享一个 OrderService
public class OrderService { }
@Component
@Scope("prototype") // 每次 getBean/注入都是全新实例
public class ReportBuilder { }
经典陷阱: 把 prototype 注入到 singleton 里。singleton 只被装配一次,所以它会永远持有那唯一的一个 prototype 实例——"每次都新建"的承诺就破了。用 @Lookup、ObjectProvider<ReportBuilder> 或作用域代理(scoped-proxy)来修复。
@Component
public class ConnectionPool {
@PostConstruct // 在依赖注入完成之后、被使用之前运行
public void open() { /* 打开 socket、预热缓存 */ }
@PreDestroy // 在容器优雅关闭时运行(仅 singleton)
public void close() { /* 释放资源 */ }
}
重要:Spring 不会对 prototype bean 调用 @PreDestroy——它把它们交出去后就不再跟踪,所以它们的清理由你负责。
这能区分把 Spring 当作魔法的人和真正理解容器的人。singleton 持有 prototype 的 bug 是面试的宠儿,因为它很微妙且会引发真实的生产问题。知道 singleton 必须是无状态且线程安全的(它们被所有请求线程共享)是面试官想听到的实用要点。