Kotlin spring-boot @ConfigurationProperties

4.7k views Asked by At

I'm trying to create the following bean AmazonDynamoDBAsyncClientProvider. I've application.properties that defines endpoint and tablePrefix which I'm trying to inject using @ConfigurationProperties

Following is the code snippet for the same. When I run my spring-boot app it doesn't work.

I've tried doing the same ConfigurationProperties class using a regular java class which does set those properties but when it comes to AmazonDynamoDBAsyncClientProvider, the properties are empty. What am I missing here?

@Component
open class AmazonDynamoDBAsyncClientProvider @Autowired constructor(val dynamoDBConfiguration: DynamoDBConfig){

@Bean open fun getAmazonDBAsync() = AmazonDynamoDBAsyncClientBuilder.standard()
        .withEndpointConfiguration(
                AwsClientBuilder.EndpointConfiguration(dynamoDBConfiguration.endpoint, dynamoDBConfiguration.prefix))
        .build()
}

here is the kotlin bean that I'm trying to autowire with configuration

@Component
@ConfigurationProperties(value = "dynamo")
open class DynamoDBConfig(var endpoint: String="", var prefix: String="")

finally heres the regular java bean that does get populated with ConfigurationProperties but when it gets Autowired I see those properties being empty/null

@Component
@ConfigurationProperties("dynamo")
public class DynamoDBConfiguration {
private String endpoint;
private String tablePrefix;

public String getEndpoint() {
    return endpoint;
}

public void setEndpoint(String endpoint) {
    this.endpoint = endpoint;
}

public String getTablePrefix() {
    return tablePrefix;
}

public void setTablePrefix(String tablePrefix) {
    this.tablePrefix = tablePrefix;
}
}
3

There are 3 answers

0
Dummyc0m On

Have you tried getting rid of the @Component annotation on your ConfigurationProperties class?

Here is what I have done with Kotlin and Spring, hope it helps.

I am trying to leverage the kotlin-spring and kotlin-allopen gradle plugin

dependencies {
    classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlinVersion"
    classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion"
}
apply plugin: 'kotlin-spring'
apply plugin: 'kotlin-noarg'
noArg {
    annotation("your.noarg.annotation.package.NoArg")
}

They do make spring development with kotlin a lot easier.

@ConfigurationProperties("dynamo")
@NoArg
data class DynamoDBConfiguration(var endpoint: String, var prefix: String)
0
seg On

I tried your configuration class and it gets populated. I think your mistake is in the way you are trying to create the bean, the function needs to be in a class annotated with @Configuration, this should work:

@Configuration
class Beans {
    @Bean
    fun getAmazonDBAsync(config: DynamoDBConfiguration) = 
        AmazonDynamoDBAsyncClientBuilder.standard()
        .withEndpointConfiguration(
            AwsClientBuilder.EndpointConfiguration(config.endpoint, config.prefix)
        )
        .build()
}

Spring will inject the config for you, as long as you annotate the config with @Component, like you did above.

0
Thami Bouchnafa On

I had a similar problem and fixed it this way:

I defined the configuration properties class with lateinit vars:

@ConfigurationProperties(prefix = "app")
open class ApplicationConfigProperties {
     lateinit var publicUrl: String
}

Then configured a bean in my spring boot application:

@SpringBootApplication
open class Application {
     @Bean open fun appConfigProperties() = ApplicationConfigProperties()
}