首先,Spring中Bean创建的生命周期分为以下几个步骤:
- Bean实例化
- 属性设置(依赖注入)
- Aware回调(例如BeanNameAware、BeanFactoryAware)
- BeanPostProcessor前置处理
- 初始化方法调用
- BeanPostProcessor后置处理
下面我们来一步步分析每一个步骤。
Bean实例化
在Spring容器中,Bean实例化通常有两个过程:实例化和初始化。实例化是创建Bean实例的过程,通常是通过构造函数或工厂方法进行的。初始化是为Bean设置属性,通常是通过依赖注入完成的。
对于实例化过程,我们来看一个示例,假设有一个类叫做MyBean
:
public class MyBean {
public MyBean() {
System.out.println("MyBean: 实例化");
}
}
在Spring容器中,使用如下方式配置 MyBean:
<bean id="myBean" class="com.example.MyBean"/>
当我们启动应用程序时,会看到输出 MyBean: 实例化
,这表示MyBean已经成功实例化。
属性设置(依赖注入)
在实例化Bean后,Spring会为Bean注入属性,也就是依赖注入。依赖注入有多种方式,例如:
- 构造函数注入
- Setter方法注入
- 属性注入
下面我们以Setter方法注入为例,假设有另外一个类叫做MyBeanDep
,它需要注入到MyBean
中作为一个依赖:
public class MyBeanDep {
public void init() {
System.out.println("MyBeanDep: 初始化");
}
}
我们将MyBeanDep
注入到MyBean
中:
<bean id="myBeanDep" class="com.example.MyBeanDep"/>
<bean id="myBean" class="com.example.MyBean">
<property name="myBeanDep" ref="myBeanDep"/>
</bean>
这里我们使用<property>
标签来设置属性,其中name属性指定了要设置的属性名,ref属性指定了要注入的依赖Bean的ID。
Aware回调
Aware接口是Spring提供的一组接口,实现这些接口的Bean可以获取Spring容器的一些资源,例如Bean的名称、BeanFactory等。 例如,我们可以实现BeanNameAware接口,获取自己在Spring容器中的名称:
public class MyBean implements BeanNameAware {
private String name;
public void setBeanName(String name) {
this.name = name;
}
}
在Spring容器中,我们这样配置MyBean:
<bean id="myBean" class="com.example.MyBean"/>
启动应用程序时,Spring会调用setBeanName
方法,并将MyBean在容器中的名称传入。
BeanPostProcessor前置处理
BeanPostProcessor是Spring提供的一个接口,可以用来在Bean实例化、初始化过程中对Bean进行处理。Spring内置了许多实现了BeanPostProcessor接口的类,例如ApplicationContextAwareProcessor、AutowiredAnnotationBeanPostProcessor等。
例如,我们可以实现一个简单的BeanPostProcessor,打印出Bean的实例化和初始化方法被调用的时间:
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
System.out.println(name + ": 处理前置处理,当前时间:" + new Date());
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
System.out.println(name + ": 处理后置处理,当前时间:" + new Date());
return bean;
}
}
在Spring容器中,我们这样配置Bean:
<bean id="myBeanPostProcessor" class="com.example.MyBeanPostProcessor"/>
<bean id="myBean" class="com.example.MyBean">
<property name="myBeanDep" ref="myBeanDep"/>
</bean>
启动应用程序,我们可以看到输出类似于以下内容:
myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:40:03 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:40:04 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:40:04 CST 2021
MyBeanDep: 初始化
myBean: 处理后置处理,当前时间: Thu Aug 19 23:40:04 CST 2021
初始化方法调用
初始化方法是Spring容器为Bean设置完属性、完成Aware回调、执行完BeanPostProcessor前置处理后调用的方法。 在Spring中,Bean可以通过实现InitializingBean接口或在配置文件中使用init-method属性来指定初始化方法。
例如,我们在MyBean
类中定义初始化方法:
public class MyBean implements InitializingBean {
public void afterPropertiesSet() throws Exception {
System.out.println("MyBean: 初始化");
}
}
在Spring容器中,我们这样配置Bean:
<bean id="myBean" class="com.example.MyBean">
<property name="myBeanDep" ref="myBeanDep"/>
<init-method>afterPropertiesSet</init-method>
</bean>
启动应用程序,我们可以看到输出类似于以下内容:
myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:50:29 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:50:30 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:50:30 CST 2021
MyBeanDep: 初始化
MyBean: 初始化
myBean: 处理后置处理,当前时间: Thu Aug 19 23:50:30 CST 2021
BeanPostProcessor后置处理
BeanPostProcessor后置处理是在Bean初始化方法调用后执行的。有时候我们需要在Bean初始化后做一些其他的操作,例如缓存Bean或者检查Bean状态是否正确。
例如,我们实现一个BeanPostProcessor,输出Bean是否已正确初始化:
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
if (bean instanceof MyBean) {
MyBean myBean = (MyBean) bean;
if (myBean.getMyBeanDep() != null) {
System.out.println("MyBean已正确初始化!");
} else {
System.out.println("MyBean未正确初始化!");
}
}
return bean;
}
}
启动应用程序,我们可以看到输出类似于以下内容:
myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:56:47 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:56:48 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:56:48 CST 2021
MyBeanDep: 初始化
MyBean已正确初始化!
myBean: 处理后置处理,当前时间: Thu Aug 19 23:56:48 CST 2021
通过上述示例,我们可以清晰了解Spring中Bean创建的完整生命周期及其每一个步骤。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring创建Bean的生命周期详析 - Python技术站