一、生命周期
Bean 的生命周期指的是在 Spring 容器中,一个 Bean 创建到销毁的整个过程。这个过程包括了 Bean 实例化、依赖注入、初始化、使用和销毁等多个阶段。
Bean 的生命周期包括以下阶段:
-
Bean 的实例化:根据配置或代码创建一个 Bean 实例。在这个阶段中,Spring 容器会根据配置或代码生成一个 Bean 的实例。
-
属性赋值:将配置或代码中的属性值赋给 Bean 实例。在这个阶段中,Spring 容器会将配置文件或者代码中指定的属性值注入到 Bean 实例中,例如通过构造函数、属性的 setter 方法、注解等方式进行注入。
-
实现 Aware 接口:Spring 将容器相关的信息注入 Bean 实例,例如实现 BeanNameAware 接口可获取 Bean 的名称。在这个阶段中,Spring 容器会将容器相关的信息注入到 Bean 实例中,例如实现 BeanNameAware 接口可获取 Bean 的名称,实现 ApplicationContextAware 接口可获取应用上下文对象等。
-
检查 Bean 的配置信息是否正确。在这个阶段中,Spring 容器会对 Bean 进行检查,确保其配置信息正确。
-
执行自定义的初始化方法,可通过配置或代码指定。在这个阶段中,Spring 容器会执行用户自定义的初始化方法,例如通过配置文件中的 init-method 属性或者实现 InitializingBean 接口的 afterPropertiesSet() 方法进行指定。
-
实现 BeanPostProcessor 接口:在初始化之前或之后执行一些自定义的操作。在这个阶段中,Spring 容器会在 Bean 初始化之前或之后执行用户自定义的操作,例如通过实现 BeanPostProcessor 接口,实现 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 方法来进行处理。
-
Bean 已经完成初始化,可供其他对象使用。在这个阶段中,Bean 实例已经完成了初始化并且准备好被其他对象使用了。
-
实现 DisposableBean 接口:当 Bean 被销毁时执行销毁操作,可通过配置或代码指定。在这个阶段中,Spring 容器会在 Bean 被销毁时执行用户自定义的销毁方法,例如通过配置文件中的 destroy-method 属性或者实现 DisposableBean 接口的 destroy() 方法进行指定。
二、生命周期控制
在 Spring 中,控制 Bean 的生命周期可以使用以下方式:
1. 实现 InitializingBean 和 DisposableBean 接口
通过实现 InitializingBean 接口和 DisposableBean 接口,可以在 Bean 初始化和销毁时执行自定义的逻辑。InitializingBean 接口提供了 afterPropertiesSet() 方法,该方法会在 Bean 初始化完成后被调用;DisposableBean 接口提供了 destroy() 方法,该方法会在 Bean 销毁之前调用。
- 定义一个需要使用到 InitializingBean 和 DisposableBean 接口的 Bean 类。
public class MyBean implements InitializingBean, DisposableBean {
private String name;
public void init() {
System.out.println("MyBean 初始化完成");
}
public void destroy() {
System.out.println("MyBean 正在销毁...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet() 方法调用");
init();
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy() 方法调用");
destroy();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 在 Spring 配置文件中注册 MyBean 类,并设置它的属性值。
<bean id="myBean" class="com.example.MyBean">
<property name="name" value="My Bean"/>
</bean>
启动 Spring 容器,观察控制台输出。
通过上述步骤,当 Spring 容器启动时,会自动调用 MyBean 类的构造方法,再调用其 setName 方法设置属性值。然后,Spring 容器会自动调用 InitializingBean 接口的 afterPropertiesSet 方法,输出 InitializingBean.afterPropertiesSet() 方法调用 日志,进而调用 MyBean 类的 init 方法。当 Spring 容器准备销毁 Bean 时,会自动调用 DisposableBean 接口的 destroy 方法,输出 DisposableBean.destroy() 方法调用 日志,进而调用 MyBean 类的 destroy 方法。
2. 在 XML 配置中添加 init-method 和 destroy-method 属性
在 Bean 的 XML 配置中可以添加 init-method 属性和 destroy-method 属性,这两个属性分别指定 Bean 初始化和销毁时需要调用的自定义方法。在 XML 配置中,可以通过添加 init-method 和 destroy-method 属性来控制 Bean 的初始化和销毁时执行的方法。具体步骤如下:
- 在 Bean 的 XML 配置中,添加 init-method 和 destroy-method 属性,分别指定 Bean 初始化和销毁时需要调用的自定义方法。
<bean id="myBean" class="com.example.MyBean" init-method="init" destroy-method="destroy"/>
- 在 MyBean 类中定义 init() 和 destroy() 方法,并实现相应的逻辑。这里假设 init() 方法打印一条初始化完成的日志,destroy() 方法打印一条销毁前的日志。
public class MyBean {
public void init() {
System.out.println("MyBean 初始化完成");
}
public void destroy() {
System.out.println("MyBean 准备销毁");
}
}
当 Spring 容器初始化时,会自动调用 MyBean 类的 init() 方法,输出一条初始化完成的日志。当 Spring 容器准备销毁 Bean 时,会自动调用 MyBean 类的 destroy() 方法,输出一条销毁前的日志。
3. 实现 BeanPostProcessor 接口
通过实现 BeanPostProcessor 接口,可以在 Bean 初始化的不同阶段执行自定义的逻辑。BeanPostProcessor 接口提供了 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 两个方法,分别在 Bean 初始化之前和之后被调用。
通过实现 BeanPostProcessor 接口,可以在 Spring 容器中所有 Bean 的初始化前后执行相应的逻辑。具体步骤如下:
- 定义一个 BeanPostProcessor 实现类,实现 postProcessBeforeInitialization 和 postProcessAfterInitialization 两个方法。这里以一个简单的示例来说明。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before Initialization, Bean Name: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("After Initialization, Bean Name: " + beanName);
return bean;
}
}
- 在 Spring 配置文件中注册 BeanPostProcessor 实现类。
<bean id="myBeanPostProcessor" class="com.example.MyBeanPostProcessor"/>
- 定义一个需要使用到 BeanPostProcessor 的 Bean 类。
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 在 Spring 配置文件中注册 MyBean 类,并设置它的属性值。
<bean id="myBean" class="com.example.MyBean">
<property name="name" value="My Bean"/>
</bean>
- 启动 Spring 容器,观察控制台输出。
通过上述步骤,当 Spring 容器启动时,会自动调用 MyBeanPostProcessor 实现类的 postProcessBeforeInitialization 方法,输出 Before Initialization 日志。然后再调用 MyBean 类的 setName 方法设置属性值。最后,Spring 容器会自动调用 MyBeanPostProcessor 实现类的 postProcessAfterInitialization 方法,输出 After Initialization 日志。
通过实现 BeanPostProcessor 接口,可以在 Spring 容器中所有 Bean 的初始化前后执行相应的逻辑。这种方式比较适合需要在 Bean 初始化前后执行一些通用操作的场景。