Spring03: bean的生命周期; bean后处理器介入的骚操作; 模板方法设计模式

bean的生命周期是一道很常见的面试题, 用代码具象化一下,很容易就理解了.

@Slf4j
@Component
public class LifeCycleBean {
    public LifeCycleBean(){
        log.info("构造方法,实例化");
    }
    @Autowired
    public void autowired(@Value("${spring.application.name}") String name){
        log.info("属性注入{}",name);
    }

    //注解直译: 构造函数 后
    @PostConstruct
    public void init(){
        log.debug("初始化");
    }
    //注解直译: 销毁 前
    public void destroy(){
        log.debug("销毁");
    }
}

基本就是按照这几个步骤,

1.实例化,先调用构造方法创建对象,
2.注入属性
3. 初始化
4. 销毁

测试可以在Application类中 run后给它close关掉,来模拟销毁.

/**
 * 启动类
 *
 * @author linnine09
 * @since 2022-04-10,v1.0.0
 */
@SpringBootApplication
public class A03Application {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
        ConfigurableApplicationContext context = SpringApplication.run(A03Application.class);

        context.close();
    }

}

大概的日志是这样的
在这里插入图片描述
最后是销毁
在这里插入图片描述


前面在讲BeanFactory的时候就有讲到bean的后处理器, 通过这些后处理器还可以在bean的生命周期中做一些增加的骚操作.

回忆一下, PostProcessor 拆开来就是: Post后置 Processor处理器 所以就是后置处理器

主要是这两个接口InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor

实例化后置处理器,和销毁后置处理器

@Slf4j
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (beanName.equals("lifeCycleBean"))
            log.debug("<<<<<<<<<<< 实例化前执行,如@PreDestroy");
        // 返回null保持原有对象不变,返回不为null,会替换掉原有对象
        return null;
        //return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

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

        return true;
        //return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

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

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

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("lifeCycleBean"))
            log.debug("<<<<<<<<<<< 初始化之后执行,这里返回的对象会替换掉原本的bean,如 代理增强");
        return bean;
        //return InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
    @Override
    public void postProcessBeforeDestruction(Object o, String beanName) throws BeansException {
        if(beanName.equals("lifeCycleBean"))
            log.debug("<<<<<<<<<<<销毁之前执行");
    }

}

比如说 需要对一些类做一些统一的处理操作,就可以在这里实现,这里是对类名进行判断, 如果没有判断 每个类执行这些步骤时都会打印.

在这里插入图片描述
在这里插入图片描述

补充一个模板方法的设计模式

/**
 * 模板方法
 */
public class TestMethodTemplate {

    public static void main(String[] args) {
        //原本的后处理器工厂里面没有处理器
        MyBeanFactory myBeanFactory = new MyBeanFactory();
        //在外部实现起方法后 加入到处理器工厂
        myBeanFactory.addProcesses(bean -> System.out.println("解析@Autowired"));
        myBeanFactory.addProcesses(bean -> System.out.println("解析@Resource"));
        //在内部遍历调用处理器来进行实现,方便对方法进行外部扩展
        Object bean = myBeanFactory.getBean();
    }

    static class MyBeanFactory{

        public Object getBean(){
            Object bean = new Object();
            System.out.println("构造");
            System.out.println("依赖注入");
            //一般的我们后续要补充一些操作,比如添加一些后置处理器,需要改变此处的代码
            //但是每次都来改造这个方法,会使这个代码变得臃肿 也就是扩展性差
            //所以我们可以定义一个方法工厂,将一些方法的实现注入进后,在此处拿来使用
            processes.forEach(process-> process.inject(bean));
            System.out.println("初始化");
            return bean;
        }

        //一般有两种结构的工厂 一种是map型 一种是list型
        //map 主要用于1对1 传不同的类进来,根据需求去调用处理类
        //list 主要用于1对多 不管传什么类进来, 我都要走一遍全部的处理
        public static List<BeanPostProcess> processes=new ArrayList<>();

        /**
         * 这里提供一个口子 供外部传入实现类
         * @param beanPostProcess
         */
        public void addProcesses(BeanPostProcess beanPostProcess){
            processes.add(beanPostProcess);
        }

    }
    //后置处理器接口 把方法抽象化 把需求定下 外部自行实现
    interface BeanPostProcess{
        void inject(Object bean);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值