@IT·互联网

Bean的生命周期

2023-12-19  本文已影响0人  我可能是个假开发

一、Bean的生命周期

一个受 Spring 管理的 bean,生命周期主要阶段有:

@SpringBootApplication
public class BeanPostProcessorTest {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(BeanPostProcessorTest.class, args);
        context.close();
    }
}
@Component
public class LifeCycleBean {
    private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        log.info("构造");
    }

    @Autowired
    public void autowire(@Value("${JAVA_HOME}") String home) {
        log.info("依赖注入: {}", home);
    }

    @PostConstruct
    public void init() {
        log.info("初始化");
    }

    @PreDestroy
    public void destroy() {
        log.info("销毁");
    }
}
package com.hcx.springdemo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 {

    private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);


    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.info("<<<<<< 销毁之前执行, 如 @PreDestroy");
        }
    }


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            log.info("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
        }
        return null;
    }


    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
            // 跳过依赖注入
//            return false;
        }
        //继续执行
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")) {
            log.info("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
        }
        return bean;
    }
}
[INFO ] 15:26:06.434 [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 789 ms 
[INFO ] 15:26:06.460 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean 
[INFO ] 15:26:06.462 [main] com.hcx.springdemo.LifeCycleBean    - 构造 
[INFO ] 15:26:06.464 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段 
[INFO ] 15:26:06.464 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource 
[INFO ] 15:26:06.465 [main] com.hcx.springdemo.LifeCycleBean    - 依赖注入: 'abc' 
[INFO ] 15:26:06.466 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties 
[INFO ] 15:26:06.466 [main] com.hcx.springdemo.LifeCycleBean    - 初始化 
[INFO ] 15:26:06.466 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强 
[INFO ] 15:26:06.673 [main] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 
[INFO ] 15:26:06.691 [main] o.s.b.w.e.tomcat.TomcatWebServer    - Tomcat started on port(s): 8080 (http) with context path '' 
[INFO ] 15:26:06.699 [main] c.h.s.BeanPostProcessorTest         - Started BeanPostProcessorTest in 1.372 seconds (JVM running for 1.958) 
[INFO ] 15:26:06.720 [main] c.h.springdemo.MyBeanPostProcessor  - <<<<<< 销毁之前执行, 如 @PreDestroy 
[INFO ] 15:26:06.720 [main] com.hcx.springdemo.LifeCycleBean    - 销毁 

1.创建前后的增强

2.依赖注入前的增强

3.初始化前后的增强

4.销毁之前的增强

二、模版方法模式

public class TestMethodTemplate {

    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
        beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
        beanFactory.getBean();
    }

    // 模板方法  Template Method Pattern
    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造 " + bean);
            System.out.println("依赖注入 " + bean); // @Autowired, @Resource
            for (BeanPostProcessor processor : processors) {
                processor.inject(bean);
            }
            System.out.println("初始化 " + bean);
            return bean;
        }

        private List<BeanPostProcessor> processors = new ArrayList<>();

        public void addBeanPostProcessor(BeanPostProcessor processor) {
            processors.add(processor);
        }
    }
    
    static interface BeanPostProcessor {
        public void inject(Object bean); // 对依赖注入阶段的扩展
    }
}
上一篇 下一篇

猜你喜欢

热点阅读