【问题标题】:Spring Kotlin @ConfigurationProperties for data class defined in dependencySpring Kotlin @ConfigurationProperties 用于依赖项中定义的数据类
【发布时间】:2021-07-07 16:33:45
【问题描述】:

我有一个库,它有一个定义为数据类的配置类(没有 spring 配置类)。我想要一个可以通过 application.properties 配置的配置的 Bean。问题是我不知道如何告诉 Spring 根据该外部数据类创建 ConfigurationProperties。我不是配置类的作者,所以我不能注释类本身。 @ConfigurationProperties 与 @Bean 一起不起作用,因为属性是不可变的。这甚至可能吗?

【问题讨论】:

    标签: spring kotlin spring-kotlin


    【解决方案1】:

    也许更改扫描包以包含您想要的包。

     @SpringBootApplication( scanBasePackages = )
    

    看看这个: Configuration using annotation @SpringBootApplication

    【讨论】:

    • 对不起,这在我的描述中不是很清楚,但是该类不是弹簧配置类。
    • 使用@Bean public AppName getAppName(@Value("${app.name}") String appName) { return () -> appName; }
    • 是的,但是对于很多选项,这将是很多样板文件,我认为可能有一种方便的方法可以将外部依赖项的类标记为 ConfigurationPorperties 类。
    • 我明白了,但是如果你的外部类没有 spring 注释,这是唯一的方法。
    • 似乎是唯一的可能
    【解决方案2】:

    如果我理解正确,您是否需要一种将第三方对象转换为具有 application.properties 文件中属性的 bean 的方法?

    给定一个application.properties 文件:

    third-party-config.params.simpleParam=foo
    third-party-config.params.nested.nestedOne=bar1
    third-party-config.params.nested.nestedTwo=bar2
    

    创建一个类以从属性文件中接收参数

    import org.springframework.boot.context.properties.ConfigurationProperties
    import org.springframework.context.annotation.Configuration
    
    @Configuration
    @ConfigurationProperties(prefix = "third-party-config")
    data class ThirdPartConfig(val params: Map<String, Any>)
    

    这是您要使用的对象的示例

    class ThirdPartyObject(private val simpleParam: String, private val nested: Map<String, String>) {
    
    fun printParams() =
        "This is the simple param: $simpleParam and the others nested ${nested["nestedOne"]} and ${nested["nestedTwo"]}"
    
    }
    

    使用将第三方对象转换为可注入 bean 的方法创建配置类。

    import org.springframework.context.annotation.Bean
    import org.springframework.context.annotation.Configuration
    
    @Configuration
    class ThirdPartObjectConfig(private val thirdPartConfig: ThirdPartConfig) {
    
    @Bean
    fun thirdPartyObject(): ThirdPartyObject {
        return ThirdPartObject(
            simpleParam = thirdPartConfig.params["simpleParam"].toString(),
            nested = getMapFromAny(
                thirdPartConfig.params["nested"]
                    ?: throw IllegalStateException("'nested' parameter must be declared in the app propertie file")
                )
            )
        }
    
        private fun getMapFromAny(unknownType: Any): Map<String, String> {
            val asMap = unknownType as Map<*, *>
            return mapOf(
                "nestedOne" to asMap["nestedOne"].toString(),
                "nestedTwo" to asMap["nestedTwo"].toString()
            )
        }
    }
    

    所以现在您可以将您的第三方对象作为 bean 注入您的 application.properties 文件中的自定义配置参数

    @SpringBootApplication
    class StackoverflowAnswerApplication(private val thirdPartObject: ThirdPartObject): CommandLineRunner {
      override fun run(vararg args: String?) {
        println("Running --> ${thirdPartObject.printParams()}")
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 2013-07-12
      • 2015-09-12
      相关资源
      最近更新 更多