Spring Framework核心概念之Bean生命周期管理

[TOC]html

Spring Bean的生命周期

Spring容器既Application或者WebApplication会在管理Bean的时候;为了尽量的把本身内部的东西机制暴露出来给用户使用,因此在Bean建立的过程当中加了不少机制,经过所谓的"处理器"Processor暴露出来,而后处理器都有本身的顺序,咱们须要作的就是定义好处理器的逻辑,而后注册到Sprinhg容器中,Spring就会调用了。下面就是Spring管理Bean的生命周期图。java

img

img

下面这张图描述的更为详细。web

相关接口的分类

对于上面图看不懂不要着急由于你并不认识与生命周期相关的接口。Spring生命周期你能够理解为四个等级;每一个等级中都用有相应的接口,实现其中某个接口或者将实现类注入到Sprng容器,容器就会在相应的时机调用其方法。详细信息可看下面的一个表格。spring

  • 工厂后处理器接口方法
  • 容器级生命周期接口方法
  • Bean级生命周期接口方法
  • Bean自己方法
分类 接口 调用时间
工厂后处理器接口 BeanFactoryPostProcessor 容器建立完毕,装配Bean源后当即调用
容器后处理器接口 InstantiationAwareBeanPostProcessor 分别在调用构造以前,注入属性以前,实例化完成时调用
容器后处理器接口 BeanPostProcessor 分别在Bean的初始化方法调用先后执行
Bean级后置处理器接口 BeanNameAware 注入属性后调用
Bean级后置处理器接口 BeanFactoryAware 注入属性后调用
Bean级后置处理器接口 InitializingBean 在类自己的初始化方法以前调用其方法(自己也是初始化方法)
Bean级后置处理器接口 DiposableBean 在类自己的销毁方法执行以前调用其方法(自己也是销毁方法)
Bean自己方法 init方法 在注入属性以后调用初始化方法
Bean自己方法 destroy方法 在关闭容器的时候进行销毁

测试SpringBean生命周期的Demo程序

本测试程序来自https://www.cnblogs.com/zrtqsk/p/3735273.html 我在这里说一下测试程序是如何测试SpringBean的生命周期的。首先将一个工厂后处理器 BeanFactoryPostProcessor接口实现注入容器,再将容器后处理器InstantiationAwareBeanPostProcessorBeanPostProcessor注入容器,又在自定义Person实现了Bean级后处理器BeanNameAwareBeanFactoryAwareInitializingBeanDiposableBean接口的相关方法,最后就是在自定义的Person类中实现了其自己的init()方法和destroy()方法。springboot

  • 自定义Person类
public class Person implements BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean {

    private String name;
    private String address;
    private int phone;

    private BeanFactory beanFactory;
    private String beanName;

    public Person() {
        System.out.println("【构造器】调用Person的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("【注入属性】注入属性address");
        this.address = address;
    }

    public int getPhone() {
        return phone;
    }

    public void setPhone(int phone) {
        System.out.println("【注入属性】注入属性phone");
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Person [address=" + address + ", name=" + name + ", phone="
                + phone + "]";
    }

    // 这是BeanFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out
                .println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }

    // 这是BeanNameAware接口方法
    @Override
    public void setBeanName(String arg0) {
        System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
        this.beanName = arg0;
    }

    // 这是InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out
                .println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
    }

    // 这是DiposibleBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
    }

    // 经过<bean>的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
    }

    // 经过<bean>的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
    }
}
  • MyBeanPostProcessor (实现容器级别后置处理器)
public class MyBeanPostProcessor implements BeanPostProcessor {
    public MyBeanPostProcessor() {
        super();
        System.out.println("这是BeanPostProcessor实现类构造器!!");
        // TODO Auto-generated constructor stub
    }

    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1)
            throws BeansException {
        System.out
                .println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
        return arg0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1)
            throws BeansException {
        System.out
                .println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
        return arg0;
    }
}
  • MyInstantiationAwareBeanPostProcessor(实现容器级别后置处理器)
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调用postProcessBeforeInstantiation方法");
        return null;
    }

    // 接口方法、实例化Bean以后调用
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out
                .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
        return bean;
    }

    // 接口方法、设置某个属性时调用
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs,
                                                    PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out
                .println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
        return pvs;
    }
}
  • MyBeanFactoryPostProcessor (实现容器级别后置处理器)
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("person");
        bd.getPropertyValues().addPropertyValue("phone", "110");
    }
}
  • 配置Spring的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-3.2.xsd">

    <bean id="beanPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanPostProcessor">
    </bean>

    <bean id="instantiationAwareBeanPostProcessor"
          class="com.jimisun.learnspringboot.web.MyInstantiationAwareBeanPostProcessor">
    </bean>

    <bean id="beanFactoryPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanFactoryPostProcessor">
    </bean>

    <bean id="person" class="com.jimisun.learnspringboot.web.Person" init-method="myInit"
          destroy-method="myDestory" scope="singleton" p:name="张三" p:address="广州"
          p:phone="15900000000"/>

</beans>
  • Main方法执行测试
public class Main {
    public static void main(String[] args) {

        System.out.println("如今开始初始化容器");

        ApplicationContext factory = new ClassPathXmlApplicationContext("bens.xml");
        System.out.println("容器初始化成功");
        //获得Preson,并使用
        Person person = factory.getBean("person",Person.class);
        System.out.println(person);

        System.out.println("如今开始关闭容器!");
        ((ClassPathXmlApplicationContext)factory).registerShutdownHook();
    }

}
  • 测试结果(我对Main方法执行结果作了格式化,方便参照)

LOGGER测试:如今开始初始化容器
    【工厂构造】这是BeanFactoryPostProcessor实现类构造器!!
    【工厂方法】BeanFactoryPostProcessor调用postProcessBeanFactory方法
        【容器构造】这是BeanPostProcessor实现类构造器!!
        【容器构造】这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
        【容器方法】InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
            【类构造】调用Person的构造器实例化
        【容器方法】InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
                【类注入属性】注入属性address
                【类注入属性】注入属性name
                【类注入属性】注入属性phone
                【Bean方法:BeanNameAware接口】调用BeanNameAware.setBeanName()
                【Bean方法:BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
            【容器方法】BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
                【Bean方法:InitializingBean接口】调用InitializingBean.afterPropertiesSet()
                【自身方法:init-method】调用<bean>的init-method属性指定的初始化方法
            【容器方法】BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
        【容器方法】InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
LOGGER测试:容器初始化成功
    Person [address=广州, name=张三, phone=110]
LOGGER测试:如今开始关闭容器!
                【Bean级别:DiposibleBean接口】调用DiposibleBean.destory()
                【自身方法:destroy-method】调用<bean>的destroy-method属性指定的初始化方法

将Demo代码的执行结果与上述表中的执行时机进行对比,看看执行时机是否正确,框架

小结

理解透彻Spring Bean的生命周期对开发中能够解决比较棘手的问题,对于深刻学习Spring Framework框架这是必需要掌握的知识,因此能够多看两遍。ide

该教程所属Java工程师之Spring Framework深度剖析专栏,本系列相关博文目录 Java工程师之Spring Framework深度剖析专栏post

原文出处:https://www.cnblogs.com/jimisun/p/10098467.html学习

相关文章
相关标签/搜索