在Java项目的开发当中,Spring框架现在已经被非常广泛地运用。其中了解Bean的生命周期,是对框架理解和熟练运用非常有必要的。一般开发当中通常也是运用ApplicationContext作为Spring的容器,因此这里探讨的也是ApplicationContext中bean的生命周期。
以下为个人理解的流程图:
代码示例:
public class Person implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean, ApplicationContextAware {
private String name;
private String address;
private String phone;
private BeanFactory beanFactory;
private String beanName;
public Person() {
System.out.println("【构造器】调用Person的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】注入属性name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【注入属性】注入属性address");
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
System.out.println("【注入属性】注入属性phone");
this.phone = phone;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
", phone=" + phone +
", beanFactory=" + beanFactory +
", beanName='" + beanName + '\'' +
'}';
}
// 这是DiposibleBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("【DisposableBean接口】DisposableBean.destroy()");
}
// 这是InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
// 这是BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = beanFactory;
}
// 这是BeanNameAware接口方法
@Override
public void setBeanName(String name) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
this.beanName = beanName;
}
private void myInit() {
System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
}
private void myDestroy() {
System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【ApplicationContextAware】接口调用setApplicationContext");
}
}
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
/**
* BeanPostProcessor接口包括2个方法postProcessAfterInitialization和postProcessBeforeInitialization,
* 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。这里要注意。
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!!");
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
System.out.println(bean.toString());
return bean;
}
}
/**
* InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口,
* 一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它
* <p>
* 这个有3个方法,其中第二个方法postProcessAfterInitialization就是重写了BeanPostProcessor的方法。
* 第三个方法postProcessPropertyValues用来操作属性,返回值也应该是PropertyValues对象
*/
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
执行结果:
现在开始初始化容器
18:12:42.405 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3f102e87
18:12:42.543 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 5 bean definitions from class path resource [beans.xml]
18:12:42.564 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanFactoryPostProcessor'
这是BeanFactoryPostProcessor实现类构造器!!
BeanFactoryPostProcessor调用postProcessBeanFactory方法
18:12:42.576 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
18:12:42.629 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanPostProcessor'
这是BeanPostProcessor实现类构造器!!
18:12:42.641 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'instantiationAwareBeanPostProcessor'
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
18:12:42.645 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【注入属性】注入属性address
【注入属性】注入属性name
【注入属性】注入属性phone
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
【ApplicationContextAware】接口调用setApplicationContext
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
Person{name='张三', address='广州', phone=110, beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@704a52ec: defining beans [org.springframework.aop.config.internalAutoProxyCreator,beanPostProcessor,instantiationAwareBeanPostProcessor,beanFactoryPostProcessor,person]; root of factory hierarchy, beanName='null'}
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用<bean>的init-method属性指定的初始化方法
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
容器初始化成功
Person{name='张三', address='广州', phone=110, beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@704a52ec: defining beans [org.springframework.aop.config.internalAutoProxyCreator,beanPostProcessor,instantiationAwareBeanPostProcessor,beanFactoryPostProcessor,person]; root of factory hierarchy, beanName='null'}
关闭容器
18:12:42.659 [SpringContextShutdownHook] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@3f102e87, started on Wed Jun 02 18:12:42 CST 2021
【DisposableBean接口】DisposableBean.destroy()
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
由此可见,bean的创建历经了各种各样的方法,以下对他们的进行一下总结:
大概的流程:
- 实例化
- 赋值
- 初始化
- 销毁
- 对多个bean产生影响:BeanPostProcessor、InstantiationAwareBeanPostProcessor
- 对单个bean产生影响:BeanNameAware、BeanFactoryAware、ApplicationContextAware等,包括各种init/destory-method
至此,个人对于Spring Bean的生命周期理解大概就是这样,理解的时候结合代码自己捣鼓一下,梳理逻辑起来会更加清晰。