Spring Bean 作用域详解
Spring 容器默认采用单例模式(singleton),但根据业务需求,Bean 还可以配置为其他作用域。了解这些作用域的区别,对于管理内存和状态至关重要。
1. Singleton(单例)
这是 Spring 容器的默认作用域。在整个应用上下文中,只存在一个 Bean 实例,所有请求共享同一个对象引用。它最适合无状态的服务组件,比如 DAO、工具类或核心业务逻辑。
2. Prototype(原型)
每次请求都会生成一个新的 Bean 实例。这种模式适用于需要保持会话状态的组件。这里有个关键点需要注意:Spring 容器只管创建和依赖注入,不管后续的销毁。一旦把实例交给客户端,容器就不再过问它的生命周期,你需要自己负责清理资源。
3. Request / Session / Global Session
这三个作用域仅在 Web 应用中有效。
- Request:每次 HTTP 请求创建一个新实例,请求结束即销毁。适合存储请求相关的数据。
- Session:针对某个 HTTP Session 创建实例,Session 失效时销毁。适合保存用户会话数据。
- Global Session:类似 Session,但在 Portlet 环境下共享全局 Session。如果是标准 Servlet 应用,会降级为普通 Session 作用域。
Bean 生命周期解析
理解 Bean 的生命周期,有助于我们掌握何时介入初始化或销毁逻辑。
实例化时机
- Singleton:容器启动时立即实例化。可以通过
lazy-init="true"改为首次使用时加载,或在<beans>标签设置default-lazy-init="true"全局延迟。 - Prototype:每次调用
getBean()时实例化。
完整生命周期流程
当 Spring 容器加载配置后,Bean 的处理顺序大致如下:
- 实例化:通过默认构造器或指定参数创建对象。
- 属性赋值:根据配置调用 Setter 方法注入依赖。
- Aware 接口回调:如果实现了
BeanNameAware、BeanFactoryAware或ApplicationContextAware,容器会传入相应引用。 - 前置处理:调用关联的
BeanPostProcessor.postProcessBeforeInitialization()。 - 初始化:执行配置的
init-method或实现InitializingBean接口的afterPropertiesSet()。 - 后置处理:调用
BeanPostProcessor.postProcessAfterInitialization()。此时 Bean 已准备就绪,可被正常使用。 - 销毁:容器关闭时,若实现了
DisposableBean接口则调用destroy(),或执行配置的destroy-method。
注意,对于 Prototype 类型的 Bean,上述销毁步骤通常不会由容器自动触发,务必在业务代码中手动管理资源释放。
下面是一个简单的上下文示例,展示如何加载配置:
ApplicationContext ctx ( []{});

