Spring的生命周期主要指创建、初始化、销毁。Bean的生命周期主要由容器进行管理,我们可以自定义bean的初始化和销毁方法,容器在bean进行到生命周期的特定时间点,来调用自定义的初始化和销毁方法。

示例代码地址:https://gitee.com/codingee/day-st/tree/sping_cyclelife/

一 初始化和销毁方式

1.1 指定初始化前方法和容器销毁后方法

init-method destory-method

  1. 单实例bean下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
  2. 多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean
package com.st.spring.cycle.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * \* Created with IntelliJ IDEA.
 * \* @author: wucj
 * \* @date: 2020/9/16 12:58
 * \* @description:
 * \
 */
@Slf4j
public class CycleOne {

    public CycleOne() {
        log.info("{}...constructor...",this.getClass().getSimpleName());
    }

    public void init(){
        log.info("{}...init...",this.getClass().getSimpleName());
    }


    public void destory(){
        log.info("{}...destory...",this.getClass().getSimpleName());
    }
}

1.2 让Bean实现InitializingBean, DisposableBean 接口

package com.st.spring.cycle.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * \* Created with IntelliJ IDEA.
 * \* @author: wucj
 * \* @date: 2020/9/16 12:58
 * \* @description:
 * \
 */
@Slf4j
public class CycleTwo implements InitializingBean, DisposableBean {

    public CycleTwo() {
        log.info("{}...constructor...", this.getClass().getSimpleName());
    }

    // 容器移除对象之后调用
    @Override
    public void destroy() throws Exception {
        log.info("{}...destroy...", this.getClass().getSimpleName());
    }

    // 对象创建并赋值完成之后调用
    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("{}...afterPropertiesSet...", this.getClass().getSimpleName());
    }
}

1.3 使用jsr250规则(java规范)定义的两个注解来实现

package com.st.spring.cycle.bean;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * \* Created with IntelliJ IDEA.
 * \* @author: wucj
 * \* @date: 2020/9/16 12:58
 * \* @description:
 * \
 */
@Slf4j
public class CycleThree{

    public CycleThree() {
        log.info("{}...constructor...", this.getClass().getSimpleName());
    }

    // 容器移除对象之后调用
    @PreDestroy
    public void methord1(){
        log.info("{}...destroy...", this.getClass().getSimpleName());
    }

    // 对象创建并赋值完成之后调用
    @PostConstruct
    public void methord2() {
        log.info("{}...afterPropertiesSet...", this.getClass().getSimpleName());
    }
}

bean注入到容器中:

package com.st.spring.cycle.config;

import com.st.spring.cycle.bean.CycleOne;
import com.st.spring.cycle.bean.CycleThree;
import com.st.spring.cycle.bean.CycleTwo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * \* Created with IntelliJ IDEA.
 * \* @author: wucj
 * \* @date: 2020/9/16 12:57
 * \* @description:
 * \
 */
@Configuration
// 扫描指定包路径下的所有bean
@ComponentScan("com.st.spring.cycle.bean")
public class CycleConfig {
    /**
     * 自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
     * 注意1:单实例下可以调用实例的initMethod和destoryMethod方法,多实例无法调用。
     * 注意2:
     * @return
     */
    @Bean(initMethod = "init",destroyMethod = "destory")
    // 多实例不能调用initMethod和destoryMetod方法
    // @Scope("prototype")
    public CycleOne cycleOne(){
        return new CycleOne();
    }

    @Bean
    public CycleTwo cycleTwo(){
        return new CycleTwo();
    }

    @Bean
    public CycleThree cycleThree(){
        return new CycleThree();
    }
}

容器启动和销毁:

package com.st.spring;

import com.st.spring.cycle.config.CycleConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * \* Created with IntelliJ IDEA.
 * \* @author: wucj
 * \* @date: 2020/9/16 13:01
 * \* @description: bean生命周期源码跟踪与学习
 * \
 */
public class CycleConfigTest {

    public static void main(String[] args) {
        // 启动容器
        AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(CycleConfig.class);

        /**
         * 注意1:单实例下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
         * 注意2:多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean
         * @return
         */
        // 关闭容器
        app.close();
    }
}

只有以上三种可以实现bean的自定义初始化和销毁调用;

二 后置处理器

后置处理器负责在初始化方法前后调用;

接口BeanPostProcessor是bean的后置处理器,在bean初始化前、后进行方法拦截;

方法1:

default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   return bean;
}

调用时机:在任何初始化方法调用之前进行后置处理工作(initMethod之前、initializingBean的afterPropertiesSet初始化之前)

方法2:

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   return bean;
}

调用时机:在任何初始化方法调用之后进行后置处理工作(initMethod之后、initializingBean的afterPropertiesSet初始化之后)

总结:单实例bean的整个生命周期都可以进行控制;

三 容器启动及BeanPostProcessor源码分析

针对CycleConfigTest进行debug:以下所有断点位置都是源码的位置,请使用示例源码项目断点:下载

断点1:org/springframework/context/annotation/AnnotationConfigApplicationContext.java:89

refresh();

断点2:org/springframework/context/support/AbstractApplicationContext.java:551

// Instantiate all remaining (non-lazy-init) singletons. 实例化非懒加载单例bean
				finishBeanFactoryInitialization(beanFactory);

断点3:org/springframework/context/support/AbstractApplicationContext.java:879

// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();

断点4:org/springframework/beans/factory/support/DefaultListableBeanFactory.java:864

getBean(beanName);

断点5:org/springframework/beans/factory/support/DefaultListableBeanFactory.java:897

return doGetBean(name, null, null, false);

断点6:org/springframework/beans/factory/support/AbstractBeanFactory.java:201

断点7:org/springframework/beans/factory/support/AbstractBeanFactory.java:244

断点8:org/springframework/beans/factory/support/AbstractBeanFactory.java:324

return createBean(beanName, mbd, args);

断点9:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:478

断点10:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:516

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

断点11:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:548

断点12:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:593

populateBean(beanName, mbd, instanceWrapper); // 属性赋值
exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化
断点13:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1786
// 初始化方法调用之前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

断点14:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1790

// 初始化
invokeInitMethods(beanName, wrappedBean, mbd);

断点15:org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java:1798

// 初始化方法调用后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);