栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot测试类使用@ConfigurationProperties无法注入值

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot测试类使用@ConfigurationProperties无法注入值

印象中一直有@ConfigurationProperties无法注入的情况,当时换其它方法解决了,也就没在意。

而今天准备自动注入配置文件中的多个配置项目,到一个List,显然不能再用以前那种方法,会非常麻烦。

使用@ConfigurationProperties(prefix = “spring.redis.cluster”),一直为null。

那换@Value("${spring.redis.cluster.urls}")注入试试。

还是不行,@Value注入解析不了数据结构。

解决方法

首先,需要gettersetter方法。
其次,启动类上加上@EnableConfigurationProperties,这个注解作用就是启用对@ConfigurationProperties注解的支持。

注入测试:

原理探究

授人以鱼不如授人以渔。

为什么测试时不行?

正常启动SpringBoot时能注入的,而使用SpringBootTest启动就无效。

这个很好分析,一提到SpringBoot我们直接想到自动装配,来吧,一定能在spring-boot-autoconfigure.jar的spring.factories中找到你想要的东西(重要,知道了这一步就能任你探究SpringBoot的原理):

来到ConfigurationPropertiesAutoConfiguration,看到@EnableConfigurationProperties注解,也就完全验证了我们的想法。

也就是在@SpringBootApplication环境下,这些都给配置好了,因此@ConfigurationProperties才有效。

小结

我们在SpringBootTest测试时,有时只需要功能测试,非集成测试。此时,处于未自动装配ConfigurationPropertiesAutoConfiguration的情况,因此@ConfigurationProperties也就不会生效。

继续探究原理
  1. 且看@EnableConfigurationProperties,噢,原来只是个标记,最终配置逻辑在EnableConfigurationPropertiesRegistrar。

  2. 实现了importBeanDefinitionRegistrar,具备动态注册Bean的功能。

  3. 动态注册了ConfigurationPropertiesBindingPostProcessor这个BeanPostProcessor,用于在Bean的初始化前后回调。

  4. 启动容器,debug看看创建Bean的生命周期中干了什么。

    我写的配置类是:@ConfigurationProperties(prefix = “spring.redis.cluster”) RedisConfig。

    下面是创建RedisConfig这个Bean的调用栈。


    看下面代码,有个ConfigurationProperties,也就是在这一步会解析需要注入配置的Bean上写的@ConfigurationProperties。从而根据其prefix找到yml中属性,注入到Bean实例的属性中。

  5. bind方法调用后,被创建的Bean的实例的属性上也就有值了。

小结
  1. @EnableConfigurationProperties的原理是@import了EnableConfigurationPropertiesRegistrar。
  2. 实现EnableConfigurationPropertiesRegistrar利用importBeanDefinitionRegistrar动态注册了ConfigurationPropertiesBindingPostProcessor。
  3. 在getBean->createBean->applyBeanPostProcessorsBeforeInitialization->bind方法中根据当前实例化的Bean上的@ConfigurationProperties完成注册。

    关键点:applyBeanPostProcessorsBeforeInitialization。
    该方法会循环调用了所有BeanPostProcessor的postProcessBeforeInitialization方法,也就包含了ConfigurationPropertiesBindingPostProcessor。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322104.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号