• 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
    个人理解,如有错误,欢迎指正!
  • 相关阅读:
    Oracle 的merge into 用法
    个人博客作业——结课总结
    个人博客作业week7
    结对项目总结博客
    #个人博客作业week3——微软必应词典的使用
    #个人博客作业week2——结对编程伙伴代码复审
    #个人博客作业week2——关于代码规范的个人观点
    #个人博客作业——目前流行的源程序版本管理软件和项目管理软件优缺点
    个人项目——四则运算题目的随机生成
    #个人博客作业Week1——浏览教材后提出的六个问题及软件与软件工程的提出。
  • 原文地址:https://www.cnblogs.com/gllegolas/p/11850444.html
Copyright © 2020-2023  润新知