在 Spring 框架中,Bean 是用于管理对象的核心组成部分。Spring 的 IoC 容器通过 Bean 的作用域来控制它们的生命周期。理解 Spring Bean 的作用域和生命周期对于开发灵活、高效的 Spring 应用至关重要。
Spring Bean 的五种作用域
Spring 提供了五种 Bean 作用域,每种作用域决定了 Bean 的创建、使用和销毁方式:
-
singleton(单例,默认作用域)
- 定义:整个 Spring IoC 容器中,只有一个实例。
- 生命周期:容器启动时创建 Bean,关闭时销毁;Bean 被共享,因此每次引用时返回的都是同一实例。
- 适用场景:适合无状态的 Bean,比如 DAO 类、Service 类等。
- 声明方式:
@Scope("singleton")
或不显式声明作用域(默认为 singleton)。
-
prototype(原型)
- 定义:每次请求 Bean 时都会创建一个新的实例。
- 生命周期:由调用方管理,Spring IoC 容器不负责销毁;调用
getBean
方法时创建新实例。 - 适用场景:适合需要频繁创建的、带有状态的 Bean。
- 声明方式:
@Scope("prototype")
。
-
request(Web 应用中的请求作用域)
- 定义:每个 HTTP 请求都会创建一个新的 Bean 实例,生命周期与请求一致。
- 生命周期:请求开始时创建,结束时销毁;只在 Web 环境中有效。
- 适用场景:适合与单个 HTTP 请求相关的数据处理 Bean。
- 声明方式:
@Scope("request")
。
-
session(Web 应用中的会话作用域)
- 定义:每个 HTTP 会话对应一个 Bean 实例,生命周期与会话一致。
- 生命周期:会话开始时创建,会话失效时销毁;只在 Web 环境中有效。
- 适用场景:适合与单个用户会话相关的数据处理 Bean。
- 声明方式:
@Scope("session")
。
-
application(Web 应用中的全局作用域)
- 定义:Bean 的生命周期与 ServletContext 一致,在整个 Web 应用中共享。
- 生命周期:Web 应用启动时创建,关闭时销毁。
- 适用场景:适合在整个应用中共享的 Bean。
- 声明方式:
@Scope("application")
。
Spring Bean 的生命周期
Spring Bean 的生命周期涉及从创建到销毁的整个过程,主要分为以下几个步骤:
-
实例化(Instantiation):Spring 根据配置(XML 配置或注解配置)创建 Bean 的实例。
-
属性注入(Dependency Injection):Spring 使用构造方法或 setter 方法将依赖对象注入到 Bean 中。
-
实现
BeanNameAware
接口(可选):如果 Bean 实现了BeanNameAware
接口,则会调用setBeanName()
方法,并传入该 Bean 的名称。 -
实现
BeanFactoryAware
接口(可选):如果 Bean 实现了BeanFactoryAware
接口,则会调用setBeanFactory()
方法,并传入 BeanFactory 实例。 -
实现
ApplicationContextAware
接口(可选):如果 Bean 实现了ApplicationContextAware
接口,则会调用setApplicationContext()
方法,并传入 ApplicationContext 实例。 -
Bean 的初始化方法:
@PostConstruct
注解:在@PostConstruct
方法中可以编写初始化逻辑。InitializingBean
接口:如果实现了InitializingBean
接口,则会调用其afterPropertiesSet()
方法。init-method
属性:在 XML 配置中指定的init-method
也会在此阶段调用。
-
Bean 的就绪状态:初始化完成后,Bean 进入就绪状态,可供应用程序使用。此阶段,单例作用域的 Bean 将被放入 IoC 容器中以供共享。
-
Bean 的销毁方法:
@PreDestroy
注解:在@PreDestroy
方法中编写销毁逻辑。DisposableBean
接口:如果实现了DisposableBean
接口,则会调用其destroy()
方法。destroy-method
属性:在 XML 配置中指定的destroy-method
也会在此阶段调用。
在使用原型作用域的 Bean 时,Spring 只管理 Bean 的初始化过程,不负责销毁。如果需要销毁逻辑,则需要由应用程序自行管理。
Bean 生命周期示例
以下是一个定义了初始化和销毁方法的单例 Bean 示例:
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;@Component
public class ExampleBean {public ExampleBean() {System.out.println("Bean 实例化");}@PostConstructpublic void init() {System.out.println("Bean 初始化");}public void performTask() {System.out.println("执行任务");}@PreDestroypublic void destroy() {System.out.println("Bean 销毁");}
}
Spring 启动后,输出结果如下:
Bean 实例化
Bean 初始化
执行任务
Bean 销毁
总结
-
作用域:Spring Bean 的作用域决定了它的实例化方式和生命周期。默认的
singleton
作用域适用于大多数无状态 Bean,而prototype
和其他 Web 作用域适用于带有状态的数据 Bean。 -
生命周期:Spring Bean 生命周期包含了实例化、属性注入、初始化和销毁等阶段,开发者可以通过实现特定接口或注解在这些阶段执行自定义逻辑。
了解作用域和生命周期可以帮助我们更好地控制 Bean 的使用方式,避免资源浪费和不必要的状态共享。