• 【Spring高级】第3讲 Bean的生命周期


    基本的生命周期

    为了演示生命周期的过程,我们直接使用 SpringApplication.run()方法,他会直接诶返回一个容器对象。

    import org.springframework.boot.SpringApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    
    
    @SpringBootApplication
    public class BeanLifecycleTest {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(BeanLifecycleTest.class, args);
            context.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    然后定义一个Bean,如下:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    
    @Component
    public class LifeCycleBean {
    
        public LifeCycleBean() {
            System.out.println("构造方法");
        }
    
        /**
         * 依赖注入方法
         * 当参数是一个对象时,可以直接注入
         * 但是如果是String类型,则需要使用@Value,找到环境变量JAVA_HOME
         *
         * @param home
         */
        @Autowired
        public void autowired(@Value("${JAVA_HOME}") String home) {
            System.out.println("依赖注入");
        }
    
      	/**
         *  @PostConstruct 用来标记 bean 初始化完成后的回调方法
         */
        @PostConstruct
        public void init() {
            System.out.println("初始化");
        }
    
      	/**
         * @PreDestroy 用来标记 bean 销毁前的回调方法
         */
        @PreDestroy
        public void destory() {
            System.out.println("销毁");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    上面的LifeCycleBean我们定义了构造方法、初始化方法、依赖注入方法、销毁方法。

    启动应用,打印如下:

    构造方法
    依赖注入
    初始化
    2024-02-29 22:53:29.169  INFO 39870 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2024-02-29 22:53:29.182  INFO 39870 --- [           main] c.c.demo02.chapter03.BeanLifecycleTest   : Started BeanLifecycleTest in 1.724 seconds (JVM running for 7.593)
    2024-02-29 22:53:29.191  INFO 39870 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
    销毁
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上面就可以看出整个流程。

    后处理器

    除了基本的生命周期,下面看下加上后处理器后的流程。

    import org.springframework.beans.BeansException;
    import org.springframework.beans.PropertyValues;
    import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
    import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
    import org.springframework.stereotype.Component;
    
    
    @Component
    public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessBeforeDestruction 销毁之前执行");
            }
        }
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessBeforeInstantiation 实例化之前执行");
            }
            return null;
    //        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessBeforeInstantiation 实例化之后执行");
            }
            // 如果返回false会跳过依赖注入阶段
            return true;
    //        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
        }
    
        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            //  依赖注入阶段执行,如@Autowired,@Value @Resource
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessProperties 依赖注入阶段执行");
            }
            return null;
    //        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            // 初始化之前执行,如@PostConstruct,@ConfigurationProperties
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessBeforeInitialization 初始化之前执行");
            }
            return null;
    //        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            // 一般这个阶段是替换掉原有的bean,代替增强
            if (beanName.equals("lifeCycleBean")) {
                System.out.println("<<<<< postProcessAfterInitialization 初始化之后执行");
            }
            return null;
    //        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    再次执行,结果如下

    <<<<< postProcessBeforeInstantiation 实例化之前执行
    构造方法
    <<<<< postProcessBeforeInstantiation 实例化之后执行
    <<<<< postProcessProperties 依赖注入阶段执行
    依赖注入
    <<<<< postProcessBeforeInitialization 初始化之前执行
    <<<<< postProcessAfterInitialization 初始化之后执行
    2024-02-29 23:47:57.110  INFO 42057 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2024-02-29 23:47:57.145  INFO 42057 --- [           main] c.c.demo02.chapter03.BeanLifecycleTest   : Started BeanLifecycleTest in 2.242 seconds (JVM running for 8.116)
    2024-02-29 23:47:57.158  INFO 42057 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
    <<<<< postProcessBeforeDestruction 销毁之前执行
    销毁
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过上面可以看出,各个后置处理器分别作用在Bean生命周期的哪个阶段了。

    总结

    基本生命周期

    创建
    依赖注入
    初始化
    可用
    销毁

    创建前后的增强

    • postProcessBeforeInstantiation:这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
    • postProcessAfterInstantiation:这里如果返回 false 会跳过依赖注入阶段

    依赖注入前的增强

    • postProcessProperties:如 @Autowired、@Value、@Resource

    初始化前后的增强

    • postProcessBeforeInitialization:这里返回的对象会替换掉原本的 bean,如 @PostConstruct、@ConfigurationProperties
    • postProcessAfterInitialization :这里返回的对象会替换掉原本的 bean,如代理增强

    销毁之前的增强

    • postProcessBeforeDestruction:如 @PreDestroy
  • 相关阅读:
    广州大学2023-2024学年第一学期《计算机网络》A卷
    Day39 进程
    图像实时采集系统
    使用VisualStudio制作上位机(六)
    【无标题】shell_43.Linux三种在 shell 脚本中处理选项的方法
    DDD/ABP/EF Core :新特性Owned Entity Types ,尝试另外一种值对象的配置方式
    Windows上安装和配置Apache Kafka
    Netty入门指南之NIO Buffer详解
    Linux系统安装redis并配置为服务
    【JavaScript】npm、Yarn 和 pnpm 的区别
  • 原文地址:https://blog.csdn.net/qq_43745578/article/details/136560155