Spring源码03

116 阅读1分钟

是根据黑马Spring源码课程总结的

第三讲、Bean的生命周期

1、Spring Bean的生命周期

需要的几个类,一个引导类代码如下:

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

生命周期的测试类:

@Component
public class LifeCycleBean {
    public static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);
​
    public LifeCycleBean(){
        log.debug("构造阶段");
    }
​
    @Autowired
    public void autowired(@Value("${JAVA_HOME}") String home){
        log.debug("依赖注入: {}", home);
    }
​
    @PostConstruct
    public void init(){
        log.debug("初始化阶段");
    }
​
    @PreDestroy
    public void destroy(){
        log.debug("销毁阶段");
    }
}

通过测试可以得出其生命周期图:

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

还可以使用后置处理器

@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
​
    public static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
​
    public void postProcessBeforeDestruction(Object bean,String beanName){
        if (beanName.equals("lifeCycleBean")){
            log.info("<<<<<< 销毁之前执行, 如 @PreDestroy");
        }
    }
​
    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.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段");
//            return false;
        }
        return true;
    }
​
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
        return pvs;
    }
​
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
        return bean;
    }
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
        return bean;
    }
}

完整的生命周期:

image-20210607103405031

2、设计模式——模板方法模式

基本代码:

public class TestMethodTemplate {
​
    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        beanFactory.getBean();
    }
​
    // 模板方法  Template Method Pattern
    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造 " + bean);
            System.out.println("依赖注入 " + bean);
            System.out.println("初始化 " + bean);
            return bean;
        }
    }
}

为了提高代码的可扩展度,可以通过这种方式:

public class TestMethodTemplate {
​
    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        beanFactory.getBean();
    }
​
    // 模板方法  Template Method Pattern
    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造 " + bean);
            System.out.println("依赖注入 " + bean);
            for (BeanPostProcessor postProcessor : processorList) {
                postProcessor.inject(bean);
            }
            System.out.println("初始化 " + bean);
            return bean;
        }
​
        private List<BeanPostProcessor> processorList = new ArrayList<>();
​
        public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor){
            processorList.add(beanPostProcessor);
        }
    }
​
    static interface BeanPostProcessor{
        public void inject(Object bean);
    }
}