Kotlin中object单例如何注入@ConfigurationProperties修饰的配置类属性
解决方案
Kotlin单例(object类)无法直接用@Autowired注入Spring托管Bean的问题,有两种常用的稳定实现方案:
方案1:配置类初始化赋值(最推荐,侵入性最低)
思路:通过Spring配置类的初始化回调,将Spring容器中的配置类实例主动赋值给object的公开属性。
步骤1:修改object类,声明可赋值的配置属性
object MdsCacheValidationUtil { // 声明为lateinit可变属性,等待Spring初始化时赋值 lateinit var cacheProperties: CacheProperties private val log: Logger = LoggerFactory.getLogger(this::class.java) fun validateLastUpdateTime(lastUpdateTime: Instant?) { println(cacheProperties.CacheName) //..... } }
步骤2:新增Spring配置类,完成初始化赋值
@Configuration class ObjectBeanInjectConfig( // 直接注入Spring容器中的配置属性类 private val cacheProperties: CacheProperties ) { @PostConstruct fun injectPropertiesToObject() { // Spring容器初始化完成后,主动给object的属性赋值 MdsCacheValidationUtil.cacheProperties = cacheProperties } }
注意:确保调用
MdsCacheValidationUtil的方法是在Spring上下文初始化完成之后,否则会触发lateinit属性未初始化的异常。
方案2:通过ApplicationContext静态获取Bean
思路:提前持有Spring上下文的静态引用,在object中懒加载获取需要的Bean。
步骤1:实现ApplicationContext工具类
@Component class ApplicationContextHolder : ApplicationContextAware { companion object { lateinit var context: ApplicationContext private set } override fun setApplicationContext(applicationContext: ApplicationContext) { context = applicationContext } }
步骤2:object中懒加载获取配置属性
object MdsCacheValidationUtil { // 懒加载从Spring上下文中获取配置类 private val cacheProperties: CacheProperties by lazy { ApplicationContextHolder.context.getBean(CacheProperties::class.java) } private val log: Logger = LoggerFactory.getLogger(this::class.java) fun validateLastUpdateTime(lastUpdateTime: Instant?) { println(cacheProperties.CacheName) //..... } }
额外注意事项
- 如果你使用的Spring Boot版本≥2.2,可以不用给
CacheProperties加@Component,只需要在任意配置类上加@EnableConfigurationProperties(CacheProperties::class)即可完成配置类的注册托管。 - 配置类的属性命名建议符合驼峰规范,
CacheName改成小写开头的cacheName会自动匹配配置文件中的cache.cache-name属性,避免不必要的配置绑定失败问题。
内容的提问来源于stack exchange,提问作者anastasiia_kos
相关产品推荐
相关产品推荐

