Spring容器的启动过程分为两个大的阶段:
- BeanDefinition的扫描
- 执行Bean的生命周期:实例化、属性填充、初始化过程、使用、销毁。另外,可以在初始化阶段用Aware接口和BeanPostProcessor做扩展。
下面我们通过代码验证第二个过程-Bean的生命周期:
实体类
Role
java
public class Role {
String roleName;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
Role类将作为LifeCycleBean
的依赖的实现类。
LifeCycleBean
定义Bean生命周期验证的具体实现类。
java
public class LifeCycleBean implements InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware {
/**
* 模拟普通属性的注入
*/
Integer age;
/**
* 模拟成员属性的注入
*/
Role role;
public LifeCycleBean() {
System.out.println(String.format("%s实例化完成", getClass().getSimpleName()));
}
/**
* 通过@PostConstruct调用初始化方法
*/
@PostConstruct
public void postConstruct() {
System.out.println(String.format("%s的postConstruct()被调用", getClass().getSimpleName()));
}
/**
* 通过实现InitializingBean初始化
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(String.format("%s的afterPropertiesSet()被调用", getClass().getSimpleName()));
}
/**
* 通过XML中的init-method,初始化Bean
*/
public void initMethod() {
System.out.println(String.format("%s的initMethod()被调用", getClass().getSimpleName()));
}
/**
* 通过@PreDestroy指定销毁方法
*/
@PreDestroy
public void preDestroy() {
System.out.println(String.format("%s的preDestroy()被调用", getClass().getSimpleName()));
}
/**
* 通过Disposable接口实现销毁方法
*
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println(String.format("%s的destroy()被调用", getClass().getSimpleName()));
}
/**
* 通过XML中,destroy-method指定销毁方法
*/
public void destroyMethod() {
System.out.println(String.format("%s的destroyMethod()被调用", getClass().getSimpleName()));
}
/**
* 实现ApplicationContextAware接口
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println(String.format("%s的setApplicationContext()被调用", getClass().getSimpleName()));
}
/**
* 实现BeanNameAware接口
*
* @param name
*/
@Override
public void setBeanName(String name) {
System.out.println(String.format("%s的setBeanName()被调用", getClass().getSimpleName()));
}
public void doSomething() {
System.out.println(String.format("%s正在运行", getClass().getSimpleName()));
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
System.out.println(String.format("%s的属性age被设置", getClass().getSimpleName()));
this.age = age;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
System.out.println(String.format("%s的属性role被设置", getClass().getSimpleName()));
this.role = role;
}
}
- 实例化:即对应的构造函数
- 属性填充:
age
和role
两个属性用于验证属性填充过程,age
为基本数据类型,role
为引用类型 - 初始化:实现
InitializingBean
接口,@PostConstruct
注释的postConstruct()
方法都是初始化流程;另外initMethod()
也是初始化方法,稍后由XML配置文件定义。 - Aware接口:
ApplicationContextAware
和BeanNameAware
为Aware接口,用于初始化之前的扩展 - 使用:
doSomething()
表示Bean初始化完毕后的使用 - 销毁方法:实现
DisposableBean
接口、@PreDestroy
注释的preDestroy()
方法都是销毁流程;另外,destroyMethod()
也是销毁方法,稍后由XML配置文件定义。
BeanPostProcessor
java
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* Bean初始化前被调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof LifeCycleBean){
System.out.println(String.format("Bean:%s,初始化之前调用BeanPostProcessor",beanName));
}
return bean;
}
/**
* 初始化之后被调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof LifeCycleBean){
System.out.println(String.format("Bean:%s,初始化之后调用BeanPostProcessor",beanName));
}
return bean;
}
}
XML配置文件
lefeCycle.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解方式 -->
<!-- 开启后,@PostConstruct和@PreDestroy才能生效 -->
<context:annotation-config/>
<!-- 注册BeanPostProcessor -->
<bean id="myBeanPostProcessor" class="com.ldh.processors.MyBeanPostProcessor"/>
<!-- 注册Bean -->
<bean id="role" class="com.ldh.entity.Role"/>
<bean id="lifeCycleBean" class="com.ldh.entity.LifeCycleBean" init-method="initMethod" destroy-method="destroyMethod">
<!-- 属性填充 -->
<property name="age" value="18"/>
<property name="role" ref="role"/>
</bean>
</beans>
myBeanPostProcessor
:注册MyBeanPostProcessor
的Beanrole
:注册Role
的Bean,用于属性填充到lifeCycleBean
lifeCycleBean
:注册LifeCycleBean
的Bean;init-method
用于指定初始化方法initMethod()
;destroy-method
用于指定销毁方法destroyMethod()
测试代码
java
@Test
public void lifeCycleTest(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("lifeCycle.xml");
LifeCycleBean lifeCycleBean = applicationContext.getBean(LifeCycleBean.class);
//使用Bean
lifeCycleBean.doSomething();
//关闭容器
applicationContext.close();
}
测试结果
shell
# 实例化
LifeCycleBean实例化完成
# 属性填充
LifeCycleBean的属性age被设置
LifeCycleBean的属性role被设置
# Aware接口调用
LifeCycleBean的setBeanName()被调用
LifeCycleBean的setApplicationContext()被调用
# 初始化前调用BeanPostProcessor
Bean:lifeCycleBean,初始化之前调用BeanPostProcessor
# 初始化
LifeCycleBean的postConstruct()被调用
LifeCycleBean的afterPropertiesSet()被调用
LifeCycleBean的initMethod()被调用
# 初始化后调用BeanPostProcessor
Bean:lifeCycleBean,初始化之后调用BeanPostProcessor
# 使用Bean
LifeCycleBean正在运行
# 销毁Bean
LifeCycleBean的preDestroy()被调用
LifeCycleBean的destroy()被调用
LifeCycleBean的destroyMethod()被调用