四,Bean的生命周期——BeanFactory中的Bean生命周期

Bean的出生,成长到死亡

当我们通过在spring中使用getBean()的方法来获得某个类的实例,通常这个实例都是要经过以下这些过程:

  1. 如果当前的容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor,那么在实例化bean之前,容器调用postProcessBeforeInstantiation方法。
  2. 然后根据当前的配置文件信息对当前的bean进行实例化,可能通过构造函数的方式也可能是根据工厂实例方法。
  3. 如果当前的容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor,那么在bean实例化后,容器会调用postProcessAfterInstantiation方法。
  4. 如果bean配置了属性信息,那么容器此时会进一步对bean中的属性进行处理。容器会把配置值设置到bean对应的属性中,不过在设置每个属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()。
  5. 调用bean的属性设置方法设置属性值。
  6. 如果bean实现org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName()接口方法,将配置文件中该bean对应的名称设置到bean中。
  7. 如果bean实现org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory()接口方法,将BeanFactory容器的实例设置到bean中。
  8. 如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则将调用BeanProcessor的postProcessBeforeInitializaition()接口方法对bean进行加工处理。其中,入参bean是当前正在处理的bean,而beanName是当前的bean的配置名,返回对象为加工处理后的bean。
  9. 如果bean实现了InitializingBean接口,则将调用接口的afterPropertiesSet()方法。
  10. 如果在bean中通过init-method属性定义了初始化方法,则将执行这个方法。
  11. BeanPostProcessor后处理器中定义了两个方法,一个是postProcessBeforeInitialization(),另一个是postProcessAfterInitialization(),而另一个方法就会在此时调用。
  12. 如果当前的bean的作用范围是prototype,则将bean返回给调用者,调用负责对bean后续的生命管理,spring不在管理scope=”prototype”;如果bean的作用范围是singleton,则spring会把bean放在spring IOC的缓存池中,并将bean的引用返回给调用者,spring继续负责该bean的后续处理。
  13. 如果当前的bean的作用范围是singleton,且bean实现了DisposableBean接口,在容器关闭的时候,则将调用接口的destory方法。
  14. 对于singleton的bean,如果bean通过destory-method属性指定了bean的销毁方法,那么在spring容器关闭的时候,就会执行该方法。

阶段归类

bean的完整生命周期从Spring容器着手实例化开始,直到最终销毁bean,经历的过程大概可以分为4类

  1. Bean自身的方法:自身的方法也就是在bean中通过init-method和destory-method指定的方法。
  2. Bean级生命周期接口方法:如BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean,这些接口方法由Bean类直接实现。
  3. 容器级生命周期接口方法:InstantiationAwareBeanPostProcessor和BeanPostProcessor接口实现,一般称它们的实现类为“后处理器”。
  4. 工厂处理器接口方法:包括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()

猜你喜欢

转载自blog.csdn.net/u010871004/article/details/81039958