Spring框架中Bean的生命周期包括以下几个核心阶段:
-
实例化(Instantiation):
当Spring容器需要创建一个Bean时,它会根据BeanDefinition
中的配置信息调用相应的构造函数来创建Bean对象。对于Singleton作用域的Bean,只会在第一次请求时进行实例化。 -
依赖注入(Dependency Injection, DI):
在Bean被实例化后,Spring容器会根据BeanDefinition
中的属性设置和依赖关系描述,通过setter方法、构造器参数等方式将其他Bean注入到当前Bean中。 -
初始化前回调(Initialization Callbacks Before Initialization):
- 如果Bean实现了
org.springframework.beans.factory.config.BeanPostProcessor
接口,那么其postProcessBeforeInitialization(Object bean, String beanName)
方法将在初始化之前被调用。 - 同样,如果Bean实现了
InitializingBean
接口,那么其afterPropertiesSet()
方法也会在所有必需的属性设置完成后、初始化方法执行前调用。
- 如果Bean实现了
-
初始化(Initialization):
Spring允许通过以下两种方式之一执行初始化逻辑:- 如果Bean类上存在
@PostConstruct
注解的方法,则该方法会被容器自动调用,用于完成初始化工作。 - 如果Bean定义中定义了
init-method
属性,指定的初始化方法将会在这个阶段被调用。
- 如果Bean类上存在
-
初始化后回调(Initialization Callbacks After Initialization):
- 类似地,如果Bean实现了
BeanPostProcessor
接口,那么其postProcessAfterInitialization(Object bean, String beanName)
方法将在初始化之后被调用。
- 类似地,如果Bean实现了
-
使用期(Service):
初始化完成后,Bean就处于可用状态,可以被应用程序或其他Bean通过Spring容器获取并使用。 -
销毁前回调(Destruction Callbacks Before Destruction):
- 当Spring容器关闭或决定销毁某个Bean时,如果Bean实现了
DisposableBean
接口,那么其destroy()
方法会被调用。 - 或者,如果Bean上存在
@PreDestroy
注解的方法,该方法也会在Bean销毁前被调用。 - 此外,也可以通过
destroy-method
属性在Bean定义中声明自定义的销毁方法。
- 当Spring容器关闭或决定销毁某个Bean时,如果Bean实现了
-
销毁(Destruction):
容器释放Bean占用的资源,如关闭数据库连接、清理临时文件等,并从容器管理的对象缓存中移除Bean实例(对于单例作用域)。
简而言之,Spring Bean的生命周期涵盖了从创建实例、处理依赖、初始化至最终销毁的所有过程,允许开发者在各个关键点自定义行为以满足特定需求。
注意:在Spring框架中,初始化阶段与依赖注入密切相关,但这两个概念并不完全等同。生命周期中的各个阶段是相对独立且顺序进行的:
-
依赖注入(DI):
在Bean实例化之后,Spring容器会根据BeanDefinition
中的配置信息,将其他Bean作为属性通过构造器注入、setter方法注入或其他方式注入到当前Bean中。这是为了建立对象间的依赖关系,并确保Bean具有完整的服务能力。 -
初始化(Initialization):
依赖注入完成后,初始化阶段开始。这个阶段通常包括对Bean进行进一步的设置以使其达到可使用状态,如调用由@PostConstruct
注解标记的方法或实现InitializingBean
接口后定义的afterPropertiesSet()
方法。这里的“初始化”更多指的是那些由开发者自定义的、在依赖注入之后需要执行的一些逻辑,这些逻辑可能包括但不限于数据校验、资源初始化、额外属性赋值等。
虽然从广义上讲,依赖注入也可以看作是初始化的一部分,但在Spring Bean的生命周期中,它们被明确地划分为两个不同的步骤,这是因为依赖注入主要关注的是组件之间的依赖装配,而初始化则更偏向于单个组件内部的状态准备和就绪确认。