spring bean 的生命周期的点点滴滴

一、绪论

 

这篇博文的代码其实很早就有了(在看《精通spring4.x企业应用开发实践》学习记录的),只是我没有把它写成博文,今天突然想去翻翻,找半天才找到,所以我在此记录一下,否则今后再想去看又找不到了,在此非常感谢作者,让我看到了这么细致的spring开发书籍。本篇也是在作者书籍当中的代码自己敲了过来,学习学习。

二、spring  Bean介绍

spring的bean实例化会经历多个阶段,每个阶段都为bean处理不同的逻辑和控制

三,spring Bean 的初始化过程(生命周期)

1、我在这引入书中的一张图

这张图可谓是概括了bean的生命周期全部内容,堪称经典。

我们可能会想那spring 会在什么时候去实例化bean呢?别慌,下面就行答案(嘿嘿~~~)

这里我百度的,地址:https://www.cnblogs.com/zhaoxinshanwei/p/8856318.html

Spring什么时候实例化bean,首先要分2种情况 
  第一:如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化 
  第二:如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况: 
       (1):如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取 
       (2):如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化 
       (3):如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化

 

2、代码实现之生命周期测试阶段(代码来自书籍中的测试)

定义bean 并且  implements Serializable,BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean

完整代码:

package com.bean.lifecycle;

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

import java.io.Serializable;

/**
 * bean生命周期(bean级)
 */
public class Car implements Serializable,BeanFactoryAware,BeanNameAware,InitializingBean,DisposableBean {

    private String name;
    private String color;
    private int maxSpeed;

    private BeanFactory beanFactory;
    private String benaName;

    public Car() {
        System.out.println("调用 Car 的 构造函数。。");
    }

    public String getName() {
        return name;
    }

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

    public String getColor() {
        return color;
    }

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

    public int getMaxSpeed() {
        return maxSpeed;
    }

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


    //2、BenaFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("调用BenaFactoryAware接口的setBeanFactory()方法");
        this.beanFactory=beanFactory;
    }
    //3、BeanNameAware接口方法
    @Override
    public void setBeanName(String benaName) {
        System.out.println("调用BeanNameAware接口方法接口的setBeanName()方法");
        this.benaName=benaName;

    }
    //4、InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("调用InitializingBean接口方法接口的afterPropertiesSet()方法");
    }
    //5、DisposableBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("调用DisposableBean接口方法接口的destroy()方法");
    }
    //6、通过<bean>的init-method属性指定初始化方法
    public void myInit(){
        System.out.println("调用init-method所指定的myInit()方法,并且将v属性设置为10000");
        this.maxSpeed=10000;
    }
    //7、通过<bean>的destroy-method属性指定初始化方法
    public void myDestroy(){
        System.out.println("调用destroy-method所指定的myDestroy()方法");
    }


    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", maxSpeed=" + maxSpeed +
                ", beanFactory=" + beanFactory +
                ", benaName='" + benaName + '\'' +
                '}';
    }
}

定义一个后置处理器

MyInstantiationAwareBeanPostProcessor 并且继承 InstantiationAwareBeanPostProcessorAdapter 实现 Ordered

完整代码:

package com.bean.lifecycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.core.Ordered;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;

/**
 * 后处理器(InstantiationAwareBeanPostProcessorAdapter 最终还是实现的是 BeanPostProcessor 接口)
 */
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements Ordered{

    public MyInstantiationAwareBeanPostProcessor() {
        super();
    }

    @Override
    public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
        return super.predictBeanType(beanClass, beanName);
    }

    @Override
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
        return super.determineCandidateConstructors(beanClass, beanName);
    }

    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
        return super.getEarlyBeanReference(bean, beanName);
    }

    //1、接口方法,实例化bean前调用
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        //仅对容器中的car bena处理
        if("car".equals(beanName)){
            System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
        }

        return null;
    }
    //2、接口方法,在bean实例化后调用
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
       //2-1、仅对容器中的car baen处理
        if("car".equals(beanName)){
            System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
        }
        return true;
    }
    //3、接口方法,在设置某个属性值时调用
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        //3-1、仅对容器中的car baen处理
        if("car".equals(beanName)){
            System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return super.postProcessAfterInitialization(bean, beanName);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

注意:InstantiationAwareBeanPostProcessorAdapter 最终也是实现BeanPostProcessor接口

我们再来定义一个  后处理器 MyBeanPostProcessor

完整代码如下:

package spring.lifecycle;

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

/**
 * 后处理器
 */
public class MyBeanPostProcessor implements BeanPostProcessor,Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
       if(beanName.equals("car")){
           Car car= (Car) bean;
           if(car.getName()==null||car.getName()==""){
               System.out.println("调用MyBeanPostProcessor的postProcessBeforeInitialization方法,并且设置 car 的名称为 ‘奥迪A1’");
               car.setName("奥迪A1");
           }
       }
       return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("car")){
            Car car= (Car) bean;
            if(car.getMaxSpeed()>=500){
                System.out.println("调用MyBeanPostProcessor的postProcessAfterInitialization方法,并且设置 car 的MaxSpeed 为500");
                car.setMaxSpeed(500);
            }
        }
        return bean;
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

 

定义一个  工厂 后处理器   

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor

 

完整代码如下:

package spring.lifecycle;


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 {

    //1、对car 的color 属性进行“偷梁换柱”的加工操作
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
        BeanDefinition beanDefinition = bf.getBeanDefinition("car");
        System.out.println("原来的color:"+beanDefinition.getPropertyValues().getPropertyValue("color").getValue());
        System.out.println("原来的maxSpeed:"+beanDefinition.getPropertyValues().getPropertyValue("maxSpeed").getValue());
        beanDefinition.getPropertyValues().addPropertyValue("color",
                "粉红色。。。@@@");
        System.out.println("调用BeanFactoryPostProcessor接口的postProcessBeanFactory()方法");

    }
}

 

最后来测试

package spring.lifecycle;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
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 lifeCycleInBeanFactory(){
        //1、下面两句是装载配置文件并且启动容器
//        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("calsspath:applicationContext.xml");
        Resource classPathResource = new ClassPathResource("applicationContext.xml");
        BeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) defaultListableBeanFactory);
        reader.loadBeanDefinitions(classPathResource);

        //2、向容器注册MyBeanPostProcessor后处理器
        ((ConfigurableBeanFactory)defaultListableBeanFactory).addBeanPostProcessor(new MyBeanPostProcessor());

        //3、向容器注册MyInstantiationAwareBeanPostProcessor后处理器
        ((ConfigurableBeanFactory)defaultListableBeanFactory).addBeanPostProcessor(
                new MyInstantiationAwareBeanPostProcessor());

        //4、第一次从容器中获取car ,将触发容器实例化该bean,这将引发bean生命周期的方法调用
        Car car = defaultListableBeanFactory.getBean("car", Car.class);
        car.setColor("红色");


        //5、第二次从容器中获取car,直接从缓存池中获取
        Car car1 = defaultListableBeanFactory.getBean("car", Car.class);
        //6、查看car与car1是否为同一个对象
        System.out.println("(car==car1) :"+(car==car1));

        //7、关闭容器
        ((ConfigurableBeanFactory) defaultListableBeanFactory).destroySingletons();

    }

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

 

运行结果:

总结:ApplicationContext是自动注册后置处理器,而beanFactor需要手动调用addBeanPostProcessor方法注册

代码中都有注释,到此完毕!!!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章