首页 > 技术文章 > BeanFactory中Bean的生命周期

09120912zhang 2017-10-28 14:51 原文

1.1  BeanFactory中bean生命周期图

具体过程如下:

(1) 当调用者通过getBean(beanName)向容器中请求一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor 接口

则在实例化Bean之前调用接口的 postProcessBeforeInstantiation()方法

(2)根据配置情况调用Bean的构造方法或工厂方法实例化Bean

(3)如果容器注册了InstantiationAwarePostProcessor接口,那么在实例化Bean之后,调用接口depostProcessAfterInstantiation()方法 ,可在这里对已经实例化的对象惊醒梳妆打扮

(4)如果Bean设置了属性信息,那么容器在这一步着手将配置信息设置到Bean对应的属性中,不过在调用每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postPropertyValues()方法

(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后处理器,则将调用BeanPostProcessor的Object postProcessBeforeInitialization(Object bean,String beanName) 其中bean表示实例化的对象,beanName表示此对象的名称,返回的对象为加工处理后的Bean.在此方法中用户可以对某些Bean进行特殊处理,甚至改变Bean的行为,  Spring中各种神奇的功能都通过BeanPostProcessor来实现

(9)如果Bean实现了IntializingBean接口,则将调用接口的afterPropertiesSet()方法

(10)如果在Bean中通过init-method属性定义初始化方法,则将执行这个方法

(11)BeanPostProcessor后处理器的第二个方法  ,容器再次获得对Bean的加工处理机会,postProcessAfterInitialization(Object bean,String beanName) 类似与(8)

(12)如果<bean>中指定Bean的作用范围为scope="prototype" ,则将Bean交给调用者,由调用者负责Bean的后续生命管理。如果scope="singleton",那么此实例将会被放入缓存池中,有spring容器负责Bean的生命管理

(13) 对于scope="singleton" 的Bean(默认情况) ,当容器关闭时,将触发Spring对Bean后续生命周期管理工作,如果Bean实现DisposableBean接口,那么将会调用destory()方法,释放资源,记录日志文件

(14)如果Bean中通过destory-method属性定义了销毁方法,则将执行这个方法

可以将Bean生命周期内的方法归为四类

     Bean自身的方法:如调用Bean构造函数实例化Bean、调用Setter方法设置属性值、通过<bean>的init-method和destory-method所指定的方法

      Bean级生命周期的方法:如BeanNameAware,BeanFactoryAware,InitializationBean和DisposableBean,这些接口方法直接由Bean实现

     容器级生命周期接口方法: 上图中带* 有InstantiationAwareBeanPostProcessor 和BeanPostProcessor这两个接口实现,一般称他们的实现类为后处理器类,处理器接口一般不由Bean本身实现,他们独立于Bean,

实现类以容器附加装置的形式注册到Spring容器中,当Spring创建任何对象时,这些后处理器类都会发生作用,所以这些后处理器类的影响是全局的。

     工厂后处理器接口:包括ApsectJWeavingEnabler,CustomerAutoWireConfigurer,ConfigurationClassPostProcessor 等,也是容器级的,在应用上下文装配配置文件后立即调用。

 

BeanFactory中Bean生命周期案例

Car.java类代码

package com.example;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

public class Car implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
    private String brand;
    private String color;
    private int maxSpeed;
    private BeanFactory beanFactory;
    private String beanName;

    public Car() {
        System.out.println("调用Car的构造方法!!");
    }

    public void setBrand(String brand) {
        this.brand = brand;
        System.out.println("调用SetBrand()设置属性");
    }


    public void setColor(String color) {
        this.color = color;
        System.out.println("调用SetColor()设置属性");
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
        System.out.println("调用SetMaxSpeed()设置属性");
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public String getBrand() {
        return brand;
    }

    public String getColor() {
        return color;
    }

    public void introduce() {
        System.out.println("牌子:" + this.brand + " 颜色:" + this.color + " 速度:" + this.maxSpeed);
    }

    @Override
    public String toString() {
        return "牌子:" + this.brand + " 颜色:" + this.color + " 速度:" + this.maxSpeed;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("调用BeanFactoryAware.setBeanFactory().");
        this.beanFactory = beanFactory;
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("调用BeanNameAware.setBeanName()");
        this.beanName = beanName;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("调用DisposableBean.destory()");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("调用InitializingBean的方法afterPropertiesSet()");
    }

    //通过<bean>的init-method属性所指定的初始化方法
    public void myInit() {
        System.out.println("调用init-method所指定的myInit()方法");
        this.maxSpeed = 240;
        this.brand = "蓝旗";
        this.color = "蓝色";
    }

    //通过<bean>的destory-method属性所指定的销毁方法
    public void myDestory() {
        System.out.println("调用destory-method所指定的myDestory()方法");

    }

}


 

InstantiationAwareBeanPostProcessorAdapter后处理器适配器的具体子类  MyInstantiationAwareBeanPostProcess。java代码

package com.example;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.beans.PropertyDescriptor;

public class MyInstantiationAwareBeanPostProcess extends InstantiationAwareBeanPostProcessorAdapter {
    //    接口方法:在实例化Bean之前调用
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //仅对容器中的car Bean处理
        if ("car".equals(beanName)) {
            System.out.println("InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法");
        }
        return null;
    }

    //接口方法:实例化Bean之后调用
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法");
        }
        return true;
    }

    //    接口方法:在设置某个属性的时候调用
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法");
        }
        return pvs;
    }

}

 

 BeanPostProcessor接口的实现类MyBeanPostProcessor.java代码
package com.example;

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 {

        if ("car".equals(beanName)) {
            Car car = (Car) bean;
            if (car.getColor() == null) {
                System.out.println("调用BeanPostProcessor.postProcessBeforeInitialization()方法");
                car.setColor("red");
            }
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            Car car = (Car) bean;
            if (car.getMaxSpeed() > 120) {
                car.setMaxSpeed(120);
                System.out.println("调用MyBeanPostProcessor的postProcessAfterInitialization()方法");
            }
        }
        return bean;
    }
}

beans.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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <bean init-method="myInit" destroy-method="myDestory" id="car" class="com.example.Car"
          p:brand="红旗CA72"
          p:maxSpeed="200"
    />
</beans>

BeanLifeCycle.java代码

package com.example;

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 BeanLifeCycle {

    private static void LifyCycleBeanFactory() {
        Resource resource = new ClassPathResource("com/example/beanfactory/beans.xml");
        BeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) beanFactory);
        reader.loadBeanDefinitions(resource);
        ((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
        ((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcess());
        Car car1 = (Car) beanFactory.getBean("car");
        car1.introduce();
        car1.setColor("红色");
        Car car2 = (Car) beanFactory.getBean("car");
        System.out.println("car1==car2:" + (car1 == car2));
        ((DefaultListableBeanFactory) beanFactory).destroySingletons();
    }

    public static void main(String args[]) {
        LifyCycleBeanFactory();
    }

}

 

最终运行结果

InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法
调用Car的构造方法!!
InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法
调用SetBrand()设置属性
调用SetMaxSpeed()设置属性
调用BeanNameAware.setBeanName()
调用BeanFactoryAware.setBeanFactory().
调用BeanPostProcessor.postProcessBeforeInitialization()方法
调用SetColor()设置属性
调用InitializingBean的方法afterPropertiesSet()
调用init-method所指定的myInit()方法
调用SetMaxSpeed()设置属性
调用MyBeanPostProcessor的postProcessAfterInitialization()方法
牌子:蓝旗 颜色:蓝色 速度:120
调用SetColor()设置属性
car1==car2:true
调用DisposableBean.destory()
调用destory-method所指定的myDestory()方法

 ApplicationContext中的Bean生命周期类似于BeanFactory    不同的是如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会增加一个调用该接口方法setApplicationContext()的步骤如图

以ApplicationContext实现上述一样的功能

工厂后处理器  MyBeanFactoryPostProcessor.java代码

package com.example;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

//        修改配置文件中car 的属性brand初始值为  奇瑞QQ
        BeanDefinition definition = beanFactory.getBeanDefinition("car");
        definition.getPropertyValues().addPropertyValue("brand", "奇瑞QQ");
        System.out.println("调用BeanFactoryPostProcessor的postProcessBeanFactory方法");
    }
}

 

beans.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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <bean init-method="myInit" destroy-method="myDestory" id="car" class="com.example.Car"
          p:brand="红旗CA72"
          p:maxSpeed="200"
    />
    <bean id="myBeanFactoryPostProcessor" class="com.example.MyBeanFactoryPostProcessor"/>
    <bean id="myInstantionAwareBeanPostProcessor" class="com.example.MyInstantiationAwareBeanPostProcess"/>
    <bean id="beanPostProcessor" class="com.example.MyBeanPostProcessor"/>
</beans>

 

推荐阅读