• @postconstruct注解获取不到本身的bean


    当使用@postconstruct执行某个方法时,

    其中包含applicationContext.getBean(Class) 会报空指针异常

    applicationContext.getBean(clazz)
    1. public T getBean(Class requiredType) throws BeansException {
    2. this.assertBeanFactoryActive();
    3. return this.getBeanFactory().getBean(requiredType);
    4. }

    造成这个问题的原因其实是 applicationContext.getBean(Class)  是从已经被spring实例化的对象中寻找,如果该对象还未实例化,则获取不到。

    也就是通过@PostConstruct 注解在HandlerMsgData构造函数执行完成后才执行的initAllHandler() , 此时有些对象还未被spring实例化,所以该方法获取到结果并不完整。

    如果是想通过调整bean是实例化对象初始化顺序来解决该问题,则成本比较大(大型工程中依赖关系很复杂)。

    所以最好的解决方式就是在获取时检查一次allHandler里是否存在指定数据,如果不存在则再次执行initAllHandler () , 这就相当于同步了一下缓存的数据。

    补充一下:

    Bean是什么时候被实例化的?

    对于Prototype: 在第一次请求的时候才被实例化的
    对于Singleton:
    一般在IoC容器启动的时候就被实例化,然后被缓存在内存中
    如果bean标签中有设置lazy-init=true,则会在第一次请求时才会被实例化,而不是在容器启动的时候就被实例化
    但是,当一个懒实例化的Bean依赖了一个非懒实例化的Bean,那么IOC容器在启动的时候也会实例化这个Bean,因为它必须满足单例的依赖性

    SpringBoot 全局懒加载机制

    spring boot 2.2 新增全局懒加载属性,开启后全局 bean 被设置为懒加载,需要时再去创建

    spring:
     main:
     lazy-initialization: true #默认false 关闭
    

    个别 bean 可以通过设置 「@Lazy(false)」 排除,设置为启动时加载

    @Lazy(false)
    @Configuration
    public class DemoConfig {}
    

    当然也可以指定规则实现 LazyInitializationExcludeFilter 规则实现排除

    @Bean
     LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() {
     return LazyInitializationExcludeFilter.forBeanTypes(DemoConfig.class);
    }
    

    全局懒加载的问题

    通过设置全局懒加载,我们可以减少启动时的创建任务从而大幅度的缩减应用的启动时间。但全局懒加载的缺点可以归纳为以下两点:

    • Http 请求处理时间变长。 这里准确的来说是第一次 http 请求处理的时间变长,之后的请求不受影响(说到这里自然而然的会联系到 spring cloud 启动后的第一次调用超时的问题)。

    Bean生命周期源码追踪

  • 相关阅读:
    DNSlog 注入简单笔记
    【C++ STL】模拟实现 string
    在Mac 中 pip 不存在,Python版本和pycharm对不上
    写给技术人的管理入门知识1:什么是管理
    DevOps和CI/CD以及在微服务架构中的作用
    【Linux】U盘安装的cfg引导文件配置
    JavaScript的垃圾回收机制
    深入了解快速排序和归并排序
    golang学习参考记录
    用低代码打造CRM系统 实现客户个性化管理
  • 原文地址:https://blog.csdn.net/qq_37158147/article/details/126761849