Spring Bean 的完整生命周期主要包括以下阶段:
实例化(Instantiation):Spring 容器通过调用 Bean 的构造函数来创建 Bean 的实例。这是 Bean 生命周期的第一步。
设置属性值(Setting Bean Properties):Spring 容器通过调用 Bean 的 setter 方法来设置 Bean 的属性值,包括依赖注入(Dependency Injection)。
处理 BeanNameAware 接口(BeanNameAware):如果 Bean 实现了 BeanNameAware 接口,Spring 容器会调用其 setBeanName() 方法,传递 Bean 的名称给它。
处理 BeanFactoryAware 接口(BeanFactoryAware):如果 Bean 实现了 BeanFactoryAware 接口,Spring 容器会调用其 setBeanFactory() 方法,传递 BeanFactory 给它。
处理 ApplicationContextAware 接口(ApplicationContextAware):如果 Bean 实现了 ApplicationContextAware 接口,Spring 容器会调用其 setApplicationContext() 方法,传递 ApplicationContext 给它。
BeanPostProcessor 的前置处理(BeanPostProcessor.preProcessBeforeInitialization):如果有注册的 BeanPostProcessor,Spring 容器会在 Bean 的初始化之前调用它们的 postProcessBeforeInitialization() 方法,可以在这一步对 Bean 进行额外的处理。
初始化(Initialization):Spring 容器会调用 Bean 的初始化方法,可以通过在 Bean 上标注 @PostConstruct 注解或实现 InitializingBean 接口的 afterPropertiesSet() 方法来指定初始化逻辑。
BeanPostProcessor 的后置处理(BeanPostProcessor.postProcessAfterInitialization):如果有注册的 BeanPostProcessor,Spring 容器会在 Bean 的初始化之后调用它们的 postProcessAfterInitialization() 方法,可以在这一步对 Bean 进行额外的处理。
使用(Bean in Use):Bean 已经完成初始化,可以在应用程序中使用了。
销毁(Destruction):当应用程序关闭或手动销毁 Bean 时,Spring 容器会调用 Bean 的销毁方法,可以通过在 Bean 上标注 @PreDestroy 注解或实现 DisposableBean 接口的 destroy() 方法来指定销毁逻辑。
简化阶段
【其他说明】
BeanNameAware、BeanFactoryAware、ApplicationContextAware类似处理。
在 Spring 中,Bean 实现了 BeanNameAware 接口的方式有两种:
1.实现 BeanNameAware 接口:Bean 可以实现 BeanNameAware 接口,并实现接口中的 setBeanName() 方法,用于接收 Spring 容器传递的 Bean 的名称。例如:
public class MyBean implements BeanNameAware {
private String beanName;
@Override
public void setBeanName(String name) {
this.beanName = name;
}
//...其他属性和方法
}
2.在配置文件中使用 name
属性:在 XML 或者 JavaConfig 配置文件中,可以通过设置 name
属性来显式地为 Bean 指定名称,从而实现 BeanNameAware 接口的效果。例如:
在 XML 配置中:
<bean id="myBean" class="com.example.MyBean" name="customBeanName">
<!-- 配置其他属性 -->
</bean>
在 JavaConfig 配置(通俗叫代码注解配置)中:
@Configuration
public class MyConfig {
@Bean(name = "customBeanName")
public MyBean myBean() {
// 创建 MyBean 实例并配置其他属性
return new MyBean();
}
}
当 Spring 容器创建 MyBean 实例时,会调用 MyBean 实现的 setBeanName() 方法或者使用配置文件中指定的 Bean 名称来传递 Bean 的名称,从而使得 MyBean 实现了 BeanNameAware 接口。在接下来的 Bean 生命周期中,MyBean 可以通过获取 beanName 属性来获取自己在容器中的名称。
ApplicationContextAware
和 BeanFactoryAware
是 Spring 框架中两个不同的接口,它们都用于在 Spring Bean 中获取容器的引用,但有一些区别:
-
功能:
ApplicationContextAware
接口用于获取完整的 ApplicationContext 实例,包括其父 ApplicationContext,可以用于进行更加灵活和强大的操作,如获取环境信息、获取配置信息等。而BeanFactoryAware
接口只能获取当前 Bean 所属的 BeanFactory 实例,相对来说功能较为简单,只能进行基本的 Bean 获取操作。 -
引用类型:
ApplicationContextAware
接口的引用类型是ApplicationContext
,而BeanFactoryAware
接口的引用类型是BeanFactory
。ApplicationContext
是BeanFactory
的子接口,它包含了BeanFactory
的所有功能,并且还提供了更多的功能,如国际化、事件发布、AOP 等。 -
使用时机:
ApplicationContextAware
接口适用于需要在 Bean 中获取完整的 ApplicationContext 实例的场景,比如需要访问 ApplicationContext 的环境属性、配置信息等高级功能。而BeanFactoryAware
接口适用于需要在 Bean 中获取当前 Bean 所属的 BeanFactory 实例的场景,比如需要获取其他 Bean 实例的引用等。 -
推荐使用:在现代的 Spring 应用中,推荐使用
ApplicationContextAware
接口,因为它提供了更加灵活和强大的功能,包括获取完整的 ApplicationContext 实例和支持更多的高级特性。而BeanFactoryAware
接口则相对较为简单,适用于一些简单的场景。同时,也可以使用更加细粒度的方式,如使用@Autowired
注解来注入需要的 Bean 实例,而不是直接使用ApplicationContextAware
或BeanFactoryAware
接口。