第四讲:Bean的生命周期

Bean的生命周期

  • 一、生命周期演示
  • 二、添加Bean后置处理器

简单的描述并测试Bean的生命周期(细节会在后续文章中单独讲解),并加入一些BeanPostPorcessor处理测试。

一、生命周期演示

准备一个普通的SpringBoot项目

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

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

/**
 * 测试Bean的生命周期
 *
 * @Author linqibin
 * @Date 2023/8/21 23:12
 * @Email [email protected]
 */
@SpringBootApplication
@Slf4j
public class LifeCycleApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(LifeCycleApplication.class, args);
    }

    @Component("bean01")
    static class Bean01 {

        public Bean01() {
            log.error("Bean实例化,构造函数被执行~~~~~~~~~");
        }

        @PostConstruct
        public void init() {
            log.error("Bean初始化阶段~~~~~~~~~~~~~~~");
        }

        @Autowired
        private void autowired(@Value("${JAVA_HOME}" String javaHome) {
            log.error("依赖注入阶段~~~~~~~~~~~~~~~~~{}", javaHome);
        }

        @PreDestroy
        private void destroy() {
            log.error("bean销毁阶段~~~~~~~~~~~~~~~~");
        }

    }
}

分别在内部类Bean01无参构造初始化方法init()依赖注入销毁方法

@autowired如果被加在方法上,并且方法的参数是一些普通的对象,Spring会从容器中注入这个对象,但我们的参数是String,肯定是无法注入的,我们只需要在参数前添加@Value("${}"),并指定变量的名称,就可以冲系统变量或应用变量中找到并注入。

先跑一下,看下结果:

在这里插入图片描述
可以得出执行顺序是:

Bean实例化依赖注入Bean初始化Bean销毁


二、添加Bean后置处理器

在刚才的LifeCycleApplication中添加一个内部类,方法比较多,不过大部分都是见名知意,代码如下:

@Component
    static class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {


        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            // SpringBoot中的应用程序比较多,因此我们只看自己定义的那个Bean01
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> BeforeInstantiation: 在实例化之前被执行~");
            }
            return null;
        }

        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> AfterInstantiation: 在实例化之后被执行~");
            }
            return true;
        }

        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> postProcessProperties: 在依赖注入之前被执行~");
            }
            return pvs;
        }

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> BeforeInitialization: 在初始化之前被执行~");
            }
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> AfterInitialization: 在初始化之后被执行~");
            }
            return bean;
        }

        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            if (beanName.equals("bean01")) {
                log.error(">>>>>>>>>> BeforeDestruction: 比Bean销毁方法先执行~");
            }
        }
    }

重新运行:
第四讲:Bean的生命周期_第1张图片
可以看见在创建一个Bean的各个生命周期阶段前后,都可以做很多的扩展。


最后,我们再来看下各个扩展点的作用:

  • postProcessBeforeInstantiation:该方法返回的对象,会替换原本的Bean。
  • postProcessAfterInstantiation:如果返回false,则会跳过依赖注入阶段。
  • postProcessAfterInstantiation:依赖注入阶段执行,如@Autowired@Value@Resource
  • postProcessBeforeInitialization:初始化之前执行,返回对象会替换掉原有的Bean。如@PostConstructor@ConfigurationProperties
  • `postProcessAfterInitialization``:初始化方法之后执行,返回对象会替换原有的Bean,如代理增强。
  • postProcessBeforeDestruction:销毁之前执行,如@PreDestroy

你可能感兴趣的:(Spring源码学习,java,开发语言,spring,springboot)