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?
Asked
Active
Viewed 970 times
2 Answers
0
Maybe change scan packages to inlcude the packages that do you want.
@SpringBootApplication( scanBasePackages = )
take a look this: Configuration using annotation @SpringBootApplication

jonas.lima
- 116
- 11
-
Sorry this wasn't very clear in my description but the class is no spring configuration class. – Ceryni Apr 12 '21 at 15:32
-
use @Bean public AppName getAppName(@Value("${app.name}") String appName) { return () -> appName; } – jonas.lima Apr 12 '21 at 15:54
-
yeah but for a lot of options this would be a lot of boilerplate and I thought there might be a convenient way to mark a class of an external dependency to be a ConfigurationPorperties class. – Ceryni Apr 12 '21 at 16:09
-
I understood, but if your external class doesn't have a spring annotation, this is only way to do this. – jonas.lima Apr 12 '21 at 16:54
-
1Seems to be the only possibility – Ceryni Apr 13 '21 at 20:21
0
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()}")
}
}

Almir Acioly
- 1
- 1