简体   繁体   中英

Spring Kotlin @ConfigurationProperties for data class defined in dependency

I've got a library that has a configuration class (no spring configuration class) defined as a data class. I want a Bean of that configuration which can be configured via application.properties. The problem is that I don't know how to tell Spring to create ConfigurationProperties according to that external data class. I am not the author of the configuration class so I can't annotate the class itself. @ConfigurationProperties in conjunction with @Bean does not work as the properties are immutable. Is this even possible?

Maybe change scan packages to inlcude the packages that do you want.

 @SpringBootApplication( scanBasePackages = )

take a look this: Configuration using annotation @SpringBootApplication

If I understand correctly, do you need a way to turn a third-party object into a bean with properties from your application.properties file?

Given an application.properties file:

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

Create a class to receive your params from properties file

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>)

Here is an example of the object that you want to use

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"]}"

}

Create the configuration class with a method that turns your third-party object into an injectable 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()
        )
    }
}

So now you can inject your third-party object as a bean with custom configurated params from your application.properties files

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM