世事洞明皆学识,人情练达即文章。

这一节筹备给大家解说Spring 容器中的Bean的生命周期。这一节我集体感觉还是比拟实用的,在理论工作当中常常会用到这些常识来解决一些十分辣手的问题。

ApplicationContext中Bean的生命周期

先来张图:

大家看到这张图必定是一脸懵逼。不要焦急,我来缓缓解释:从getBean(…)为触发点,Spring容器的Bean生命周期就经验了图中的生命周期,先分个类:

  • 图中绿色箭头的三个步骤(InstantiationAwareBeanPostProcessor)和粉红色箭头的两个步骤(BeanPostProcessor)为容器级的生命周期接口,当Spring每加载任何一个Bean到容器中时,这些接口都会起到如图中的几次调用。这两个处理器叫做"容器级后处理器",他们的影响是全局的,可能影响所有的Bean.
  • 图中大红色圆圈圈住的接口叫做"工厂级后处理器",相似的接口还有CustomEditorConfigurer,PropertyPlaceholderConfigurer等,这类接口只在上下文初始化的时候调用一次,其目标是实现一些配置文件的加工解决工作。
  • 剩下的就简略了,属于Bean级别的接口,专属于某个Bean所有,每个Bean实例化的时候调用本人特有的。

值得一提的是,无论是"容器级后处理器"还是"工厂级后处理器",他们都是能够配置多个的(如,配置两个BeanPostProcessor),如果想管制他们的调用程序,实现一个org.springframework.core.Ordered接口即可。当然了,个别不必,个别一类后处理器只有一个即可。

重点强调!:

这些接口的调用程序并不是一尘不变的,会轻易Spring的版本变动而变动,大家要做的是万变不离其宗,晓得可能通过这些接口在Bean初始化的时做一些属性上的操作。调用程序要依据具体的版本来本人测试。上面我会给大家来列一个例子:
public class Student implements BeanFactoryAware, BeanNameAware,        InitializingBean, DisposableBean,ApplicationContextAware {    private String name;    public Student(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        System.out.println("BeanFactoryAware......");    }    @Override    public void setBeanName(String s) {        System.out.println("BeanNameAware......");    }    @Override    public void destroy() throws Exception {        System.out.println("DisposableBean......");    }    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("InitializingBean......");    }    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        System.out.println("ApplicationContextAware......");    }}

BeanFactoryPostProcessor:

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {    public MyBeanFactoryPostProcessor() {        super();        System.out.println("这是BeanFactoryPostProcessor实现类结构器!!");    }    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)            throws BeansException {        System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory办法");        BeanDefinition bd = arg0.getBeanDefinition("student");        MutablePropertyValues propertyValues = bd.getPropertyValues();        //配置文件中的信息在加载到Spring中后以BeanDefinition的模式存在.在这里又能够更改BeanDefinition,所以能够了解为更改配置文件外面的内容//        propertyValues.add("zdy","123");    }}

BeanPostProcessor:

public class MyBeanPostProcessor implements BeanPostProcessor {    public MyBeanPostProcessor() {        super();        System.out.println("这是BeanPostProcessor实现类结构器!!");    }    @Override    public Object postProcessAfterInitialization(Object arg0, String arg1)            throws BeansException {        System.out.println("BeanPostProcessor接口办法After对属性进行更改!");        return arg0;    }    @Override    public Object postProcessBeforeInitialization(Object arg0, String arg1)            throws BeansException {        System.out.println("BeanPostProcessor接口办法Before对属性进行更改!");        return arg0;    }}

InstantiationAwareBeanPostProcessorAdapter:

public class MyInstantiationAwareBeanPostProcessor extends        InstantiationAwareBeanPostProcessorAdapter {    public MyInstantiationAwareBeanPostProcessor() {        super();        System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类结构器!!");    }    // 接口办法、实例化Bean之前调用    @Override    public Object postProcessBeforeInstantiation(Class beanClass,                                                 String beanName) throws BeansException {        System.out.println("InstantiationAwareBeanPostProcessor调用Before办法");        return null;    }    // 接口办法、实例化Bean之后调用    @Override    public Object postProcessAfterInitialization(Object bean, String beanName)            throws BeansException {        System.out.println("InstantiationAwareBeanPostProcessor调用Ater办法");        return bean;    }    // 接口办法、设置某个属性时调用    @Override    public PropertyValues postProcessPropertyValues(PropertyValues pvs,                                                    PropertyDescriptor[] pds, Object bean, String beanName)            throws BeansException {        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues办法");        return pvs;    }}

而后咱们的Main办法:

public class App {    public static void main(String[] args) {        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");        Student stu = (Student) ac.getBean("student");        stu.setName("wangwu");    }}

Spring文件最简略:(留神要把咱们本人定义的处理器全副加到容器里去)

<?xml version="1.0" encoding="UTF-8"?>        <beans        <bean id="student" class="com.zdy.Student"><constructor-arg value="zhangsan"/></bean>    <bean id="myBeanFactoryPostProcessor" class="com.zdy.MyBeanFactoryPostProcessor"></bean><bean id="myInstantiationAwareBeanPostProcessor" class="com.zdy.MyInstantiationAwareBeanPostProcessor"></bean>    <bean id="myBeanPostProcessor" class="com.zdy.MyBeanPostProcessor"></bean></beans>

而后run一下子,看后果:

这是BeanFactoryPostProcessor实现类结构器!!BeanFactoryPostProcessor调用postProcessBeanFactory办法这是InstantiationAwareBeanPostProcessorAdapter实现类结构器!!这是BeanPostProcessor实现类结构器!!InstantiationAwareBeanPostProcessor调用Before办法InstantiationAwareBeanPostProcessor调用postProcessPropertyValues办法BeanNameAware......BeanFactoryAware......ApplicationContextAware......BeanPostProcessor接口办法Before对属性进行更改!InitializingBean......InstantiationAwareBeanPostProcessor调用Ater办法BeanPostProcessor接口办法After对属性进行更改!

好了,其实大抵流程就说完了,我大抵针对Bean的生命周期说一下:Spring为了尽可能的把本人外部的货色机制裸露进去给用户应用,所以在Bean创立的过程中加了很多机制,通过所谓的"处理器"Processor裸露进去,而后处理器都有本人的程序,咱们须要做的就是定义好处理器的逻辑,而后注册到Sprinhg容器中,Spring就会调用了。

其次,还有一种形式,就是让咱们的Bean实现一些接口(相似于ApplicationContextAware),通过这种形式,在Bean初始化的某个步骤调用接口定义好的办法来传入一些信息进来,像ApplicationContextAware就把ApplicationContext给传给咱们了。

而后我给大家说几个实用点的知识点,大家记着,用到时回来翻一翻就能够了:

  1. 下面的生命周期流程图,时候的时候留神调用先后顺序,防止属性被笼罩的景象。
  2. BeanFactoryPostProcessor 次要是在Spring刚加载完配置文件,还没来得及初始化Bean的时候做一些操作。比方篡改某个Bean在配置文件中配置的内容。
  3. InstantiationAwareBeanPostProcessorAdapter 根本没什么鸟用,Bean初始化后,还没有设置属性值时调用,和BeanFactoryPostProcessor一样,能够篡改配置文件加载到内存中的信息。
  4. ApplicationContextAware:用途很大,注入了ApplicationContext到Bean中。
  5. InitializingBean:有用途,能够在Bean属性全副改完之后,再做一些定制化操作。
  6. BeanPostProcessor:没什么用,Spring框架外部应用的比拟猛,像什么AOP,动静代理,都是在这搞事。前期有工夫和大家剖析。
  7. 其余的像什么init-method,destroy办法,根本都是个陈设。。我是没怎么用过,只晓得有这么回事。

结语

好了,Bean的生命周期算上和大家分享完了,其实没什么货色,大家晓得有这么回事,能用到"后处理器"搞事的时候回来大抵看下程序即可。其次就是一些Bean实现的接口,最罕用的就是(ApplicationContextAware和InitializingBean)了。还有就是BeanPostProcessor,因为这个接口的办法里会把Bean实体以Object传进去,所以能够进行一些属性上的操作。