Bean生命周期与模板方法

Bean生命周期与模板方法

  • 本文为学习笔记
  • 目录结构:

1、bean 的生命周期

  • 四个生命周期:构造 -> 依赖注入 -> 初始化 ->销毁
  • 四个生命周期之间可以通过添加后处理器强化这个 bean

1.1、生命周期

LifeCycleBean.class

public class LifeCycleBean {
    public static final Logger logger = LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        logger.info("lifecycle 构造函数");
    }

    @Autowired
    //字符串类型默认不会做依赖注入,加@value 会在环境变量或者配置文件里面找。
    //其他类型的注入会直接在 容器里面查找对应的类型做依赖注入
    public void autowire (@Value("${JAVA_HOME}") String home){
        logger.info("依赖注入:",home);
    }

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

    @PreDestroy
    //只有单例类型会在这里被销毁,其他另有时间
    public void destroy(){
        logger.info("销毁--");
    }
}

1.2、各个生命周期之间的可操作区间

myBeanPostProcessor.class

@component
public class myBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
    public static final Logger logger = LoggerFactory.getLogger(LifeCycleBean.class);
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("销毁之前执行的方法 ,如 @preDestroy");
        }
    }


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("bean 实例化之前执行,返回不为 null 的话,会替换原来存在的bean");
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("bean 实例化之后执行,返回false 不会进行依赖注入阶段了,一般返回 true");
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("依赖注入阶段执行,这里可以追加很多后处理器 比如@autowired、@resource");
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("初始化前执行的方法 ,返回的bean会替换原来的对象,这一步可以执行@PostContruct、@ConfigurationProperties");
            logger.info("前一个是初始化方法,后一个是springboot 里面 bean的属性和配置类的键值对绑定的注解");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean")){
            logger.info("初始化之后执行,返回的bean会替换原来的对象,这一步可以执行代理增强等操作");
        }
        return bean;
    }
}

2、使用模板方法设计一个简单的 BeanFactory

  • 模板方法:

    定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
    
    在本例中即:根据 Bean 的生命周期创建 BeanFactory 的骨架,而添加后处理器的操作放在创建出来的 Bean 中。从而使得整个程序具有良好的可扩展性。添加多少,添加什么完全由子类自身实现。
    
public class testMethodTemplate {
    public static void main(String[] args) {
        //创建BeanFactory 
        myBeanFactory beanFactory = new myBeanFactory();
        //添加后处理器
        beanFactory.addPostProcessor( bean-> { System.out.println(bean + "添加 @autoWried"); });
        beanFactory.addPostProcessor( bean-> { System.out.println(bean + "添加 @resource"); });
        beanFactory.getBean();
    }

    /*
    * BeanFactory :固定的部分是四个生命周期阶段。不固定的是各个阶段的后处理器。
    * */
    static class myBeanFactory{
        public Object getBean(){
            Object bean = new Object();
            System.out.println("构造bean----");
            System.out.println("依赖注入----");
            processors.forEach(p->{
                p.inject(bean);
            });
            System.out.println("初始化----");
            return bean;
        }

        //维护一个后处理器数组
        private ArrayList<BeanPostProcessor> processors = new ArrayList<>();
        //添加后处理器的方法
        public void addPostProcessor(BeanPostProcessor postProcessor){
            processors.add(postProcessor);
        }
        //后处理器接口
        static interface BeanPostProcessor{
            void inject(Object bean);
        }
    }
}
posted @ 2022-04-06 01:11  心是冰冰的  阅读(63)  评论(0)    收藏  举报