Bean的出生,成长到死亡
当我们通过在spring中使用getBean()的方法来获得某个类的实例,通常这个实例都是要经过以下这些过程:
- 如果当前的容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor,那么在实例化bean之前,容器调用postProcessBeforeInstantiation方法。
- 然后根据当前的配置文件信息对当前的bean进行实例化,可能通过构造函数的方式也可能是根据工厂实例方法。
- 如果当前的容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor,那么在bean实例化后,容器会调用postProcessAfterInstantiation方法。
- 如果bean配置了属性信息,那么容器此时会进一步对bean中的属性进行处理。容器会把配置值设置到bean对应的属性中,不过在设置每个属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()。
- 调用bean的属性设置方法设置属性值。
- 如果bean实现org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName()接口方法,将配置文件中该bean对应的名称设置到bean中。
- 如果bean实现org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory()接口方法,将BeanFactory容器的实例设置到bean中。
- 如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则将调用BeanProcessor的postProcessBeforeInitializaition()接口方法对bean进行加工处理。其中,入参bean是当前正在处理的bean,而beanName是当前的bean的配置名,返回对象为加工处理后的bean。
- 如果bean实现了InitializingBean接口,则将调用接口的afterPropertiesSet()方法。
- 如果在bean中通过init-method属性定义了初始化方法,则将执行这个方法。
- BeanPostProcessor后处理器中定义了两个方法,一个是postProcessBeforeInitialization(),另一个是postProcessAfterInitialization(),而另一个方法就会在此时调用。
- 如果当前的bean的作用范围是prototype,则将bean返回给调用者,调用负责对bean后续的生命管理,spring不在管理scope=”prototype”;如果bean的作用范围是singleton,则spring会把bean放在spring IOC的缓存池中,并将bean的引用返回给调用者,spring继续负责该bean的后续处理。
- 如果当前的bean的作用范围是singleton,且bean实现了DisposableBean接口,在容器关闭的时候,则将调用接口的destory方法。
- 对于singleton的bean,如果bean通过destory-method属性指定了bean的销毁方法,那么在spring容器关闭的时候,就会执行该方法。
阶段归类
bean的完整生命周期从Spring容器着手实例化开始,直到最终销毁bean,经历的过程大概可以分为4类
- Bean自身的方法:自身的方法也就是在bean中通过init-method和destory-method指定的方法。
- Bean级生命周期接口方法:如BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean,这些接口方法由Bean类直接实现。
- 容器级生命周期接口方法:InstantiationAwareBeanPostProcessor和BeanPostProcessor接口实现,一般称它们的实现类为“后处理器”。
- 工厂处理器接口方法:包括AspectJWeavingEnabler,CustomAutowireConfigurer,ConfigurationClassPostProcessor等方法。工厂后处理器也是容器级的,在应用上下文装配文件后立即调用。
实战bean的实例化过程
package com.spring.beanfactory.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Person implements BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean{
private String name;
private Integer age;
private String gender;
private BeanFactory beanFactory;
private String beanName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public String getBeanName() {
return beanName;
}
public Person() {
// TODO Auto-generated constructor stub
System.out.println("调用了Person()的无参构造函数");
}
public void setAge(Integer age) {
System.out.println("调用了setAge()方法进行设置属性");
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", beanFactory=" + beanFactory
+ ", beanName=" + beanName + "]";
}
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
System.out.println("调用DisposableBean.destory()");
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("调用InitializingBean.afterPropertiesSet().");
}
@Override
public void setBeanName(String beanName) {
// TODO Auto-generated method stub
System.out.println("调用BeanNameAware.setBeanName()");
this.beanName = beanName;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
System.out.println("调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = beanFactory;
}
public void defaultInit() {
System.out.println("调用init-method所指定的deaultInit(),将age设置成80");
this.age = 10;
}
public void defaultDestory() {
System.out.println("调用destory-method所指定的defaultDestory()");
}
}
package com.spring.beanfactory.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
if("person".equals(beanName)) {
Person person = (Person)bean;
if(person.getGender() == null) {
System.out.println("调用BeanPostProcessor.postProcessBeforeInitialization(),性别gender默认为male");
person.setGender("male");
}
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
if("person".equals(beanName)) {
Person person = (Person)bean;
if(person.getAge() < 20) {
System.out.println("调用BeanPostProcessor.postProcessBeforeInitialization(),年纪调整为20");
person.setAge(20);
}
}
return bean;
}
}
package com.spring.beanfactory.lifecycle;
import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("person".equals(beanName)) {
System.out.println("InstantiationAwate BeanPostProcessor,postProcess BeforeInstantiation");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
if("person".equals(beanName)) {
System.out.println("InstantiationAwate BeanPostProcessor,postProcess AfterInstantiation");
}
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
// TODO Auto-generated method stub
if("person".equals(beanName)) {
System.out.println("Instantiation AwareBeanProcessor.postProcessPropertyValues");
}
return pvs;
}
}
package com.spring.beanfactory.lifecycle;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args) {
Resource resource = new ClassPathResource("beans.xml");
BeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory)bf);
reader.loadBeanDefinitions(resource);
((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyBeanPostProcessor());
((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
Person person1 = (Person)bf.getBean("person");
System.out.println(person1.toString());
person1.setAge(12);
Person person2 = (Person)bf.getBean("person");
System.out.println("person1是否相等于person2" + (person1 == person2));
((ConfigurableBeanFactory)bf).destroySingletons();
}
}
执行结果
InstantiationAwate BeanPostProcessor,postProcess BeforeInstantiation
调用了Person()的无参构造函数
InstantiationAwate BeanPostProcessor,postProcess AfterInstantiation
Instantiation AwareBeanProcessor.postProcessPropertyValues
调用了setAge()方法进行设置属性
调用BeanNameAware.setBeanName()
调用BeanFactoryAware.setBeanFactory()
调用BeanPostProcessor.postProcessBeforeInitialization(),性别gender默认为male
调用InitializingBean.afterPropertiesSet().
调用init-method所指定的deaultInit(),将age设置成80
调用BeanPostProcessor.postProcessBeforeInitialization(),年纪调整为20
调用了setAge()方法进行设置属性
Person [name=conjane, age=20, gender=male, beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@42d80b78: defining beans [person]; root of factory hierarchy, beanName=person]
调用了setAge()方法进行设置属性
person1是否相等于person2true
调用DisposableBean.destory()
调用destory-method所指定的defaultDestory()