Spring BeanFactory中bean的生命周期

此文章为本人原创,转载请说明出处。
https://www.jianshu.com/p/0044e351a028
作者:敲破电脑问到底

BeanFactory的继承关系

Spring BeanFactory中bean的生命周期_第1张图片
image.png

我用的Spring 4.3.1.RELEASE版本的

一个bean的一生

通过一个例子了解一下bean生命周期中的一些方法

  1. 首先定义bean类LifeCycleBean
package cn.com.servyou.xqy.burningchart.service.impl;

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 BeanLifeCycle implements BeanNameAware, BeanFactoryAware, DisposableBean, InitializingBean {

    private int age;
    private String name;
    private String beanName;
    private BeanFactory beanFactory;

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("调用自己的setAge设置age属性");
        this.age = age;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        System.out.println("设置BeanName,调用了BeanNameAware.setBeanName(String s)");
        this.beanName = beanName;
    }

    public void destroy() throws Exception {
        System.out.println("调用摧毁方法,DisposableBean.destroy()");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("我的属性已经设置好,调用了InitializingBean.afterPropertiesSet()");
    }

    @Override
    public String toString() {
        return ",age:" + this.getAge();
    }
}

BeanNameAware, BeanFactoryAware, DisposableBean, InitializingBean都是bean级别的生命周期中的一些方法的接口。

  • setBeanNameBeanNameAware的方法,设置beanName的时候会调用这个方法。
  • setBeanFactoryBeanFactoryAware的方法,设置BeanFactory的时候会调用这个方法。
  • destroy方法是DisposableBean的方法,在bean被摧毁的时候会调用。
  • afterPropertiesSet方法是InitializingBean的方法,在bean的属性被设置好的时候被调用。
  1. 设置BeanFactory容器级的一些方法,这些方法对所有的bean都是有效的,我们这里只选择namebeanLifeCycle的bean进行一些操作
package cn.com.servyou.xqy.burningchart.service.impl;

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

import java.beans.PropertyDescriptor;

public class BeanFactoryLifeCycle extends InstantiationAwareBeanPostProcessorAdapter {

    public BeanFactoryLifeCycle() {
    }

    /**
     * 实例化bean之前后处理程序
     *
     * @param aClass
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInstantiation(Class aClass, String s) throws BeansException {
        if ("beanLifeCycle".equals(s)) {
            System.out.println("beanLifeCycle还没有被实例化,method:" + "postProcessBeforeInstantiation");
        }

        return null;
    }

    /**
     * 实例化bean之后的后处理程序
     *
     * @param o
     * @param s
     * @return
     * @throws BeansException
     */
    @Override
    public boolean postProcessAfterInstantiation(Object o, String s) throws BeansException {
        if ("beanLifeCycle".equals(s)) {
            System.out.println("我已经被实例化,method:postProcessAfterInstantiation");
        }

        //这里要返回true,否则不会调用你bean定义中的设置属性值,也不会调用postProcessPropertyValues
        return true;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, PropertyDescriptor[] propertyDescriptors, Object o, String s) throws BeansException {
        if ("beanLifeCycle".equals(s)) {
            System.out.println("我的属性要被设置,method:" + "postProcessPropertyValues");
        }

        return propertyValues;
    }

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        if ("beanLifeCycle".equals(s)) {
            BeanLifeCycle cycle = (BeanLifeCycle) o;
            if (cycle.getAge() == 0) {
                cycle.setAge(999);
                System.out.println("我的age被设置为" + cycle.getAge() + ",method:postProcessBeforeInitialization");
            }

        }

        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        if ("beanLifeCycle".equals(s)) {
            BeanLifeCycle cycle = (BeanLifeCycle) o;
            if (cycle.getAge() != 0) {
                System.out.println("我原来的age" + cycle.getAge());
                cycle.setAge(0);
                System.out.println("age被更改为" + cycle.getAge() + ",method:postProcessAfterInitialization");
            }

        }

        return o;
    }

}
  • 通过继承InstantiationAwareBeanPostProcessorAdapter 类,重写他的四个方法,分别是:
  • postProcessBeforeInstantiation(实例化之前后处理器),
  • postProcessAfterInstantiation(实例化之后后处理器)这里要返回true,否则不会调用你bean定义中的设置属性值,也不会调用postProcessPropertyValues
  • postProcessPropertyValues(设置属性值之前处理器)
  • postProcessBeforeInitialization(初始化之前后处理器)
  • postProcessAfterInitialization(初始化之后后处理器)
    需要注意的是每个方法的返回值,要返回参数列表的bean,不然可能初选NPE问题。
  • 还有就是 postProcessBeforeInitialization(初始化之前后处理器),postProcessAfterInitialization(初始化之后后处理器)最终是来自于BeanPostProcessor接口,这个接口十分重要,BeanPostProcessor接口无需与代码产生耦合,可作为插件注册到Spring容器,充分对bean进行后加工。
  1. bean的xml定义:



    
        
    

  1. 通过BeanFactory容器调用类,观察它的生命周期
package cn.com.servyou.xqy.burningchart.service;

import cn.com.servyou.xqy.burningchart.service.impl.BeanFactoryLifeCycle;
import cn.com.servyou.xqy.burningchart.service.impl.BeanLifeCycle;
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;

/**
 * @author wangwenj
 */
public class Main {
    public static void main(String[] args) {
        Resource res = new ClassPathResource("spring-config/lifecycle.xml");
        BeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) factory);
        reader.loadBeanDefinitions(res);
        ((ConfigurableBeanFactory) factory).addBeanPostProcessor(new BeanFactoryLifeCycle());
        BeanLifeCycle cycle = factory.getBean(BeanLifeCycle.class);
        System.out.println(cycle.toString());

        //第二次从缓存中拿出第一次的bean
        BeanLifeCycle cycle2 = factory.getBean(BeanLifeCycle.class);
        System.out.println(cycle2.toString());

        ((DefaultListableBeanFactory) factory).destroySingleton("beanLifeCycle");

    }
}

最后的结果如下所示

beanLifeCycle还没有被实例化,method:postProcessBeforeInstantiation
调用构造方法
我已经被实例化,method:postProcessAfterInstantiation
我的属性要被设置,method:postProcessPropertyValues
设置BeanName,调用了BeanNameAware.setBeanName(String s)
设置BeanFactory,调用BeanFactoryAware.setBeanFactory(BeanFactory beanFactory)
调用自己的setAge设置age属性
我的age被设置为999,method:postProcessBeforeInitialization
我的属性已经设置好,调用了InitializingBean.afterPropertiesSet()
我原来的age999
调用自己的setAge设置age属性
age被更改为0,method:postProcessAfterInitialization
,age:0
,age:0
调用摧毁方法,DisposableBean.destroy()

ApplicationContext与BeanFactory过程也是类似的,只不过多了一个ApplicationContextAware接口,继承此接口Spring会通过setApplicationContext()方法自动注入ApplicationContext上下文。你可以调用get方法获得。

你可能感兴趣的:(Spring BeanFactory中bean的生命周期)