Spring Bean的生命周期

1. BeanFactory中Bean的生命周期

这里写图片描述

  • 1.当调用者通过getBean(beanName)向容器请求某个Bean时 如果容器注册了InstantiationAwareBeanPostProcessor接口
    在实例Bean之前 将调用接口的postProcessBeforeInstantiation()方法
  • 2.根据配置情况调用Bean构造函数或者工厂方实例化Bean
  • 3.如果容器注册了InstantiationAwareBeanPostProcessor接口 实例化Bean之后 调用该接口的postProcessAfterInstantiation()方法
  • 4.如果Bean设置了属性信息 在这一步将着手配置到bean对应的属性中 不过在设置每个属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues()方法
  • 5.调用Bean的属性设置方法设置属性值
  • 6.如果Bean实现了BeanNameAware接口 将调用setBeanName()方法 将配置文件中该Bean对应的名称设置到Bean中
    【让Bean获得配置文件中对应的配置名称】
  • 7.如果Bean实现了BeanFactoryAware接口,将调用setBeanFactory接口方法 将BeanFactory容器实例设置到Bean中
    【让接口感知容器】
  • 8.如果BeanFactory装配了BeanPostProcessor后处理器 调用BeanPostProcessor的postProcessBeforeInitialization(Object,String)方法对Bean进行加工操作
    【为容器提供对Bean进行后续加工处理的切入点 AOP 动态代理都是通过BeanPostProcessor实施的】
  • 9.如果Bean实现了InitializingBean的接口 调用afterPropertiesSet()方法
  • 10.如果在通过inti-method属性定义了初始化方法 将执行这个方法
  • 11.调用BeanPostProcessor后处理器的postProcessAfterInitialization(Object,String)方法 获得对Bean进行再次加工的机会
  • 12.如果在中指定Bean的作用范围是scope=’prototype’ 将Bean返回给调用者 调用者负责Bean后续生命的管理
    如果作用范围是scope=’singleton’ 将Bean放入Spring IoC容器的缓存池中 并将Bean引用返回给调用者
  • 13.对于scope=’singleton’的Bean 当容器关闭时 触发Spring对Bean后续生命周期的管理工作 首先如果Bean首先了DisposableBean接口 则调动接口的afterPropertiesSet()方法 可以在此释放资源记录日志
  • 14.调用destory-method中的方法

以上可以大致分为三个部分:

  • Bean自身的方法:
    调动Bean构造函数实例化Bean 调用setter设置Bean的属性以及通过init-method和destory-method指定的方法
  • Bean级生命周期接口方法:
    BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean
  • 容器级声明周期接口方法:
    InstantiationAwareBeanPostProcesor和BeanPostProcessor两个接口实现 一般称他们的实现类为后处理器

验证生命周期的例子:

package life_circle;

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

/**
 * 实现管理Bean生命周期的接口
 * Created by heqianqian on 2017/8/9.
 */
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) {
        System.out.println("调用setBrand()设置属性");
        this.brand = brand;
    }

    public String getBrand() {
        return brand;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public String getBeanName() {
        return beanName;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }

    public void introduce() {
        System.out.println("brand:" + brand
                + " color:" + color + " maxspeed:" + maxSpeed);
    }

    /**
     * BeanFactoryAware中的方法
     * 为Bean注入BeanFactory
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("调用BeanFactoryAware中的setBeanFactory方法");
        this.beanFactory = beanFactory;
    }

    /**
     * BeanNameAware中的方法
     * 将配置文件中设置的Bean的属性注入到Bean中
     */
    @Override
    public void setBeanName(String s) {
        System.out.println("调用BeanNameAware中的setBeanName方法");
        this.beanName = s;
    }


    /**
     * DisposableBean接口中的方法 用于销毁Bean
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("调用DisposableBean中的destroy方法");
    }

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

    /**
     * init-method属性中指定的方法
     */
    public void myInit(){
        System.out.println("调用init-method属性中的方法");
        this.maxSpeed = 250;
    }

    /**
     * destroy-method属性中指定的方法
     */
    public void myDestroy(){
        System.out.println("调用destroy-method属性中的方法");
    }
}
package life_circle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * MyBeanPostProcessor
 * 后处理器
 * Created by heqianqian on 2017/8/9.
 */
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        if (s.equals("car")) {
            Car car = (Car) o;
            if (car.getColor() == null) {
                System.out.println("BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色");
                car.setColor("Black");
            }
        }
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        if (s.equals("car")) {
            Car car = (Car) o;
            if (car.getMaxSpeed() > 200) {
                System.out.println("BeanPostProcessor.postProcessAfterInitialization,速度调整为200");
                car.setMaxSpeed(200);
            }
        }
        return o;
    }
}
package life_circle;

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

import java.beans.PropertyDescriptor;

/**
 * MyInstantiationAwareBeanPostProcessor
 * 自定义实例化Bean处理器
 * Created by heqianqian on 2017/8/9.
 */
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    /**
     * 在实例化Bean之前调用
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("car".equals(beanName)) {
            System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization");
        }
        return bean;
    }

    /**
     * 在实例化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;
    }
}
package life_circle;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;

/**
 * BeanLifeCycle
 * Bean生命周期测试
 * Created by heqianqian on 2017/8/9.
 */
public class BeanLifeCycle {

    private static void LifeCycleInBeanFactory() {
        //装载配置文件 并启动容器
        Resource resource = new ClassPathResource("bean_life_factory.xml", BeanLifeCycle.class.getClassLoader());
        BeanFactory factory = new XmlBeanFactory(resource);
        //向容器中注册MyBeanPostProcessor后处理器
        ((ConfigurableBeanFactory) factory).addBeanPostProcessor(new MyBeanPostProcessor());
        //向容器三种注册MyInstantiationAwareBeanPostProcessor后处理器
        ((ConfigurableBeanFactory) factory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());

        //第一次从容器中获取Car 触发容器实例化该Bean
        Car car1 = (Car) factory.getBean("car");
        car1.introduce();
        car1.setColor("红色");

        //第二次从容器中获取Car 直接从缓存池中获取
        Car car2 = (Car) factory.getBean("car");

        //查看car1和car2是否指向同一引用
        System.out.println("car1==car2:" + (car1 == car2));
        //关闭容器
        ((XmlBeanFactory) factory).destroySingletons();
    }

    public static void LifeCycleContext() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean_life_context.xml");
        Car car = (Car) ac.getBean("car");
        car.introduce();
    }


    public static void main(String[] args) throws IOException {
        LifeCycleInBeanFactory();
    }

}

运行结果:

调用Car()构造方法!
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
Disconnected from the target VM, address: '127.0.0.1:51018', transport: 'socket'
调用setBrand()设置属性
调用BeanNameAware中的setBeanName方法
调用BeanFactoryAware中的setBeanFactory方法
BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色
InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
调用InitializingBean中的afterPropertiesSet方法
调用init-method属性中的方法
BeanPostProcessor.postProcessAfterInitialization,速度调整为200
brand:BENZ color:Black maxspeed:200
调用Car()构造方法!
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
调用setBrand()设置属性
调用BeanNameAware中的setBeanName方法
调用BeanFactoryAware中的setBeanFactory方法
BeanPostProcessor.postProcessBeforeInitialization,颜色为空 设置为黑色
InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
调用InitializingBean中的afterPropertiesSet方法
调用init-method属性中的方法
BeanPostProcessor.postProcessAfterInitialization,速度调整为200
car1==car2:false

2.ApplicationContext中Bean的生命周期

ApplicationContext中Bean的生命周期和BeanFactory中类似,不同点是如果Bean实现了ApplciationContextAware接口的话 会增加一个调用setApplicationContext()的方法 在postProcessBeforeInialization()方法之后

ApplicationContext和BeanFactory的不同

ApplicationContext和BeanFactory的不同点是

  • 1.BeanFactory在初始化容器时 并没有去实例化Bean 直到通过getBean()第一次访问Bean的时候才会对Bean进行初始化
    而ApplicationContext在出初始化上下时就实例化所有的单实例Bean
  • 2.ApplicationContext可以通过反射访问XML配置文件 而BeanFactory不行 因此需要手动的add不同的处理器 而ApplicationContext可以直接在配置文件中配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值