zoukankan      html  css  js  c++  java
  • 谈谈Spring bean的生命周期(一)

    简介

    本片文章主要讲Spring IOC容器中 bean 的生命周期

    Spring bean 生命周期

    Spring 中bean的声明周期 可以分为如下4个阶段:

    1. 实例化阶段--Instantiation 调用构造函数
    2. 属性赋值阶段--Populate 设置依赖注入
    3. 初始化---Initialization 调用Init方法
    4. 销毁---Destruction 调用Destory方法

    各阶段的接口和方法

    每个阶段 都是具体的接口和方法 如果按照方法和接口的类型我们可以分为如下几类:

    1. bean 本身的接口和方法 init方法,destroy方法
    2. bean 生命周期的接口 BeanNameAware,ApplicationContextAware,BeanFactoryAware,InitializingBean,DisposableBean
    3. 容器级生命周期接口 主要有BeanPostProcessor,InstantiationAwareBeanPostProcessor
    4. 工厂级的处理接口 BeanFactoryPostProcessor

    执行流程

    刚才上面列举了 很多接口和方法 那执行的顺序是什么呢?
    BeanLifecycle 代码如下

    /**
     * @ClassName BeanLifecycle
     * @Auther burgxun
     * @Description: Spring bean 的生命周期
     * @Date 2020/4/21 12:45
     **/
    public class BeanLifecycle implements BeanNameAware, ApplicationContextAware, BeanFactoryAware,InitializingBean,
            DisposableBean {
    
        public BeanLifecycle() {
            System.out.println("========>【Bean】【BeanLifecycle】执行 构造函数");
        }
    
        @Override
        public void setBeanName(String s) {
            System.out.println("========>【Bean】【BeanNameAware】 执行方法 setBeanName -------》实例化bean后 " +
                    "为bean 注入BeanName-" + s);
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            System.out.println("========>【Bean】【ApplicationContextAware】 执行方法 " +
                    "setApplicationContext-------》实例化bean后 为bean注入ApplicationContext");
        }
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("========>【Bean】【BeanFactoryAware】 执行方法 setBeanFactory -------》实例化bean后 ");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("========>【Bean】【InitializingBean】执行方法 afterPropertiesSet -------》bean" +
                    " 实例化完成后  初始化之前调用");
        }
    
        public void beanInit() {
            System.out.println("========>【Bean】【BeanLifecycle】 执行方法 Init-Method " +
                    "-------》xml中配置bean实例化完成后 初始化方法");
        }
    
        public void beanDestroy() {
            System.out.println("========>【Bean】【BeanLifecycle】 执行方法 Destroy-Method " +
                    "-------》xml中配置销毁bean之前 回调方法" +
                    " ");
        }
    
        public void sayHello() {
            System.out.println("========>【Bean】【BeanLifecycle】执行方法  bean中方法 -------》 sayHello");
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("========>【Bean】【DisposableBean】 执行方法 destroy -------》 销毁 Bean 的回调方法");
        }
    }
    
    

    ContainerLifecycle方法如下:

    **
     * @ClassName ContainerLifecycle
     * @Auther burgxun
     * @Description: Spring 容器 生命周期
     * @Date 2020/4/21 14:44
     **/
    @Component
    public class ContainerLifecycle extends InstantiationAwareBeanPostProcessorAdapter {
        public ContainerLifecycle() {
            System.out.println("========>【Container】【ContainerLifecycle】 执行 构造函数");
        }
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】执行 " +
                    "postProcessBeforeInstantiation" +
                    "-------》Bean实例化之前调用 beanName:" + beanName);
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】执行 " +
                    "postProcessAfterInstantiation " +
                    "-------》Bean实例化之后调用 beanName:" + beanName);
            return super.postProcessAfterInstantiation(bean, beanName);
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("========>【Container】【BeanPostProcessor】 执行" +
                    "postProcessBeforeInitialization " +
                    "-------》Bean初始化之前调用 beanName:" + beanName);
            return super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("========>【Container】【BeanPostProcessor】执行 " +
                    "postProcessAfterInitialization " +
                    "-------》Bean初始化之后调用 beanName:" + beanName);
            return super.postProcessAfterInitialization(bean, beanName);
        }
    
        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】 执行 postProcessProperties " +
                    "Bean 属性赋值的时候 beanName:" + beanName);
            return null;
        }
    }
    

    FactoryLifecycle 代码如下

    /**
     * @ClassName FactoryLifecycle
     * @Auther burgxun
     * @Description: Spring beanFactory 如下
     * @Date 2020/4/21 17:32
     **/
    public class FactoryLifecycle implements BeanFactoryPostProcessor {
    
        public FactoryLifecycle() {
            System.out.println("========>【BeanFactory】【BeanFactoryPostProcessor】 执行 FactoryLifecycle " +
                    "构造函数");
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
            System.out.println("========>【BeanFactory】【BeanFactoryPostProcessor】 执行方法 " +
                    "postProcessBeanFactory ");
        }
    }
    
    

    Spring bean Test

    public class SpringTest {
    
        @Test
        public void mySpringBeanTest() {
    
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath" +
                    ":Spring-life.xml");
            BeanLifecycle beanLifecycle = (BeanLifecycle) context.getBean("beanLifecycle");
    
            beanLifecycle.sayHello();
            context.close();
        }
    }
    

    执行结果是:

    【BeanFactory】【BeanFactoryPostProcessor】 执行 FactoryLifecycle 构造函数
    【BeanFactory】【BeanFactoryPostProcessor】 执行方法 postProcessBeanFactory 
    【Container】【ContainerLifecycle】 执行 构造函数
    【Container】【InstantiationAwareBeanPostProcessor】执行 postProcessBeforeInstantiation-------》Bean实例化之前调用 beanName:beanLifecycle
    【Bean】【BeanLifecycle】执行 构造函数
    【Container】【InstantiationAwareBeanPostProcessor】执行 postProcessAfterInstantiation -------》Bean实例化之后调用 beanName:beanLifecycle
    【Container】【InstantiationAwareBeanPostProcessor】 执行 postProcessProperties Bean 属性赋值的时候 beanName:beanLifecycle
    【Bean】【BeanNameAware】 执行方法 setBeanName -------》实例化bean后 为bean 注入BeanName-beanLifecycle
    【Bean】【BeanFactoryAware】 执行方法 setBeanFactory -------》实例化bean后 为bean注入BeanFactory
    【Bean】【ApplicationContextAware】 执行方法 setApplicationContext-------》实例化bean后 为bean注入ApplicationContext
    【Container】【BeanPostProcessor】 执行postProcessBeforeInitialization -------》Bean初始化之前调用 beanName:beanLifecycle
    【Bean】【InitializingBean】执行方法 afterPropertiesSet -------》bean 实例化完成后  初始化之前调用
    【Bean】【BeanLifecycle】 执行方法 Init-Method -------》xml中配置bean实例化完成后 初始化方法
    【Container】【BeanPostProcessor】执行 postProcessAfterInitialization -------》Bean初始化之后调用 beanName:beanLifecycle
    【Bean】【BeanLifecycle】执行方法  bean中方法 -------》 sayHello
    【Bean】【DisposableBean】 执行方法 destroy -------》 销毁 Bean 的回调方法
    【Bean】【BeanLifecycle】 执行方法 Destroy-Method -------》xml中配置销毁bean之前 回调方法 
    

    那继续画个流程图吧

    graph TB A[Bean] B[BeanFactory构造] C[BeanFactoryPostProcessor-postProcessBeanFactory] D[Container构造] E[InstantiationAwareBeanPostProcessor-postProcessBeforeInstantiation] F[InstantiationAwareBeanPostProcessor-postProcessAfterInstantiation] H[Bean构造] I[InstantiationAwareBeanPostProcessor-postProcessProperties] J[BeanNameAware-setBeanName] K[BeanFactoryAware-setBeanFactory] L[ApplicationContextAware-setApplicationContext] M[BeanPostProcessor-postProcessBeforeInitialization] N[InitializingBean-afterPropertiesSet] X[Bean中Init-Method] Y[BeanPostProcessor-postProcessAfterInitialization] Z[Bean中方法] U[DisposableBean-destroy] V[Bean中Destroy-Method] A-->B Y-->Z subgraph BeanFactory B-->C end subgraph 实例化 Instantiation C-->D D-->E E-->H H-->F end subgraph 设置属性和相关依赖 Populate F-->I I-->J J-->K K-->L end subgraph 初始化 Initialization L-->M M-->N N-->X X-->Y end subgraph 销毁 Destruction Z-->U U-->V end

    好了方法的流程都整理好了

    再次小结一下
    Spring 中初始化和销毁bean的三种调用方法

    1. 通过InitializingBean/DisposableBean 接口来完成
    2. 通过在bean的元素配置上加 init-method/destroy-method来指定 调用的方法
    3. 通过@PostConstruct 或@PreDestroy注解来指定 调用方法

    他们的执行顺序是怎样的呢?
    答案是 注解》接口方法》bean元素里面配置的方法

  • 相关阅读:
    Docker 私有仓库搭建
    事务提交与不同数据库的自增方式
    多环境切换&&注解方式&&增删改返回值问题
    查询缓存&&逆向工程
    Mybatis整合Log4j、延迟加载
    关联查询
    MyBatis实现动态SQL
    输出参数resultType
    MyBatis调用存储过程执行CRUD
    两种取值符号的异同
  • 原文地址:https://www.cnblogs.com/burg-xun/p/12751007.html
Copyright © 2011-2022 走看看