spring学习(三十)--bean的生命周期

spring 容器中的bean的完整生命周期一共分为十一步完成。

1.bean对象的实例化

2.封装属性,也就是设置properties中的属性值

3.如果bean实现了BeanNameAware,则执行setBeanName方法,也就是bean中的id值

4.如果实现BeanFactoryAware,则执行setBeanFactory()方法

5.如果实现ApplicationContextAware,则执行setApplicationContext()方法

6.如果存在类实现BeanPostProcessor后处理bean,执行postProcessBeforeInitialization,可以在初始化之前执行一些方法(此方法针对所有的bean都生效)

7.如果bean实现了InitializingBean,则执行afterPropertiesSet,执行属性设置之后的操作

8.调用<bean init-method="">执行指定的初始化方法

9.如果存在类实现BeanPostProcessor则执行postProcessAfterInitialization,执行初始化之后的操作(此方法针对所有的bean都生效)

10.执行自身的业务方法

11.如果bean实现了DisposableBean,则执行destory销毁方法

12.调用<bean destory-method="">执行自定义的销毁方法

第六步和第九步可以结合aop,在初始化执行之前或者执行之后执行一些操作。

下面用例子来演示一遍:

1、首先写一个类BeanLifeCircle.java,实现了BeanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean, DisposableBean接口,通过set方法注入了name,重写了构造函数,定义了init和destroy方法:

package beanLifeCircle;

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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class BeanLifeCircle implements BeanNameAware, BeanFactoryAware,
        ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    /* 构造函数 */
    BeanLifeCircle() {
        System.out.println("第一步,实例化bean");
    }

    public String getName() {
        return name;
    }

    /* set方法 */
    public void setName(String name) {
        System.out.println("第二步,调用set方法");
        this.name = name;
    }

    /* 实现BeanNameAware接口的setBeanName方法 */
    @Override
    public void setBeanName(String name) {
        System.out.println("第三步,setBeanName被调用,调用的id名为:" + name);
    }

    /* 实现BeanFactoryAware的setBeanFactory方法 */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("第四步,setBeanFactory被调用,beanFactory为:" + beanFactory);
    }

    /* 实现ApplicationContextAware的setApplicationContext方法 */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        System.out.println("第五步,setApplicationContext被调用,applicationContext为:"
                + applicationContext);
    }

    /* 实现InitializingBean接口的afterPropertiesSet方法 */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第七步,执行afterPropertiesSet方法");
    }

    /* 该方法在spring的xml文件中通过init-method配置 */
    public void initMethod() {
        System.out.println("第八步,执行xml文件中配置的初始化方法init-method");
    }

    /* 实现DisposableBean的destroy方法 */
    public void destroy() {
        System.out.println("第十一步,执行DisposableBean的销毁方法destroy-method");
    }

    /* 该方法在spring的xml文件中通过destroy-method配置 */
    public void destroyMethod() {
        System.out.println("第十二步,执行xml文件中配置的销毁方法destroy-method");
    }
}

2、编写类MyBeanPostProcessor.java实现BeanPostProcessor接口:

package beanLifeCircle;

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

public class MyBeanPostProcessor implements BeanPostProcessor{

    /*
     * 后置处理器的postProcessorBeforeInitailization方法是在bean实例化之后、依赖注入之后、自定义初始化方法init-method之前调用
     * (例如:配置文件中bean标签添加init-method属性指定Java类中初始化方法、
     * @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口)
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        /*
                在这里,能做的事情可就不止上面的这么简单的一句输出了,它还可以过滤每个对象的ip
                还可以给所有对象添加属性或者函数,总之就是所有对象!
                其实,这里体现了AOP编程的思想,AOP呢就是面向切成编程(针对所有对象编程)
         */
        System.out.println("第六步,postProcessBeforeInitialization方法被调用,beanName=" + beanName);
        if ("beanLifeCircle".equals(beanName)) {//过滤掉bean实例ID为narCodeService
            return bean;
        }
        System.out.println("后置处理器处理bean=【"+beanName+"】开始,作用类似过滤器");
        return bean;
    }

    /*
     * 后置处理器的postProcessorAfterInitailization方法是在bean实例化之后、依赖注入之后、自定义初始化方法init-method之后调用
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out.println("第九步,postProcessAfterInitialization方法被调用");
        return bean;
    }

    
}

3、编写spring配置文件spring-beanLifeCircle.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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ">
    
    <bean id="beanLifeCircle" class="beanLifeCircle.BeanLifeCircle" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="littleBall"></property>
    </bean>
    
    <!--配置自己的后置处理器,优点类似filter-->
    <bean id="myBeanPostProcessor" class="beanLifeCircle.MyBeanPostProcessor" />
</beans>

4、编写测试类BeanLifeCircleTest.java:

package beanLifeCircle;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanLifeCircleTest {
    public static void main(String[] args) {
        //加载spring配置,初始化spring容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:springConfig/spring-beanLifeCircle.xml");
        //从spring容器中获取需要的实例化bean
        BeanLifeCircle beanLifeCircle = (BeanLifeCircle)ac.getBean(BeanLifeCircle.class);
        //执行业务方法
        System.out.println("第十步,执行业务方法" + beanLifeCircle.getName());
        //销毁spring容器
        ac.destroy();
    }
}

5、测试结果:

第一步,实例化bean
第二步,调用set方法
第三步,setBeanName被调用,调用的id名为:beanLifeCircle
第四步,setBeanFactory被调用,beanFactory为:org.springframework.beans.factory.support.DefaultListableBeanFactory@36d4b5c: defining beans [beanLifeCircle,myBeanPostProcessor]; root of factory hierarchy
第五步,setApplicationContext被调用,applicationContext为:org.springframework.context.support.ClassPathXmlApplicationContext@6996db8: startup date [Tue Nov 19 16:30:11 CST 2019]; root of context hierarchy
第六步,postProcessBeforeInitialization方法被调用,beanName=beanLifeCircle(此方法针对所有的bean都生效)
第七步,执行afterPropertiesSet方法
第八步,执行xml文件中配置的初始化方法init-method
第九步,postProcessAfterInitialization方法被调用(此方法针对所有的bean都生效)
第十步,执行业务方法littleBall
第十一步,执行DisposableBean的销毁方法destroy-method
第十二步,执行xml文件中配置的销毁方法destroy-method
个人理解,如有错误,欢迎指正!
原文地址:https://www.cnblogs.com/gllegolas/p/11850444.html