Skip to content
Home » Spring ConfigurationProperties Kotlin data class

Spring ConfigurationProperties Kotlin data class

  • by
Spring ConfigurationProperties Kotlin data class

1. Overview

In this article, we will learn to implement the Spring ConfigurationProperties using Kotlin data class.

2. Kotlin data class for ConfigurationProperties

Consider that the application property file contains the following properties.

server.error.path=/error
server.port=9000

You can bind the above properties to Kotlin fields by annotating the class using the @ConfigurationProperties. Note that the @ConfigurationProperties support properties that are hierarchical.

For example, the server.error.path is hierarchical and nested property i.e., the root server prefix property contains the error nested property. The @ConfigurationProperties support multiple prefixes that have the same root prefix like below:

@Component
@ConfigurationProperties(value = "server")
data class AppProperties(var address: String?, var error: Error) 

@Component
data class Error(var path: String?)
@SpringBootApplication
open class ConfigurationPropertiesApplication : CommandLineRunner {
	@Autowired
	lateinit var appProperties : AppProperties

	private val logger: Logger = LoggerFactory.getLogger(ConfigurationPropertiesApplication::class.java)

	override fun run(vararg args: String?) {
		logger.info(appProperties.address)
		logger.info(appProperties.error.path)
	}
}

fun main(args: Array<String>) {
	runApplication<ConfigurationPropertiesApplication>(*args)
}

3.1. Kotlin data class @ConstructorBinding

Alternatively, you can use @ConstructorBinding if your project uses the Spring Boot framework version 2.2.0.RELEASE or above.

This annotation supports binding the configuration properties to constructor arguments rather than by calling setters.

You cannot use the Constructor binding with beans that are created by the regular Spring mechanisms (e.g. @Component beans, beans created via @Bean methods, or beans loaded using @Import).

However, you can use @EnableConfigurationProperties to enable configuration properties scanning and register the class as a Spring bean. To understand this registration concept, refer to the next section.

@ConstructorBinding
@ConfigurationProperties(value = "server")
data class AppProperties(val address: String?, val error: Error)

@Component
data class Error(var path: String?)

4. Register Spring @ConfigurationProperties in a standard way

You can register the @ConfigurationProperties beans in the standard way (for example using @Bean methods, using @Component or @Configuration annotations). You can refer to this article to understand bean instantiation.

For example, the following AppProperties class is annotated with @Component, so the Spring container detects this bean during component scanning and then instantiates, and registers it as a bean.

As discussed in the previous section, this only works when the @ConfigurationProperty not annotated with @ConstructorBinding.

@Component
@ConfigurationProperties(value = "server")
data class AppProperties(var address: String?, var error: Error) 

@Component
data class Error(var path: String?)

You can access the fields or properties of this bean later in your application.

For example, we have auto wired the appProperties bean and accessing it just like any other Spring bean.

@SpringBootApplication
open class ConfigurationPropertiesApplication : CommandLineRunner {
	@Autowired
	lateinit var appProperties : AppProperties

	private val logger: Logger = LoggerFactory.getLogger(ConfigurationPropertiesApplication::class.java)

	override fun run(vararg args: String?) {
		logger.info(appProperties.address)
		logger.info(appProperties.error.path)
	}
}

fun main(args: Array<String>) {
	runApplication<ConfigurationPropertiesApplication>(*args)
}

However, if you remove the annotation @Component, then the following error appears on the application start-up.

Field appProperties in com.tedblob.profiles.ProfilesApplication required a bean of type 'com.tedblob.profiles.configurations.AppProperties' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:
Consider defining a bean of type 'com.tedblob.profiles.configurations.AppProperties' in your configuration.

5. Register using the @EnableConfigurationProperties

Alternatively, you can also use this @EnableConfigurationProperties annotation to support the @ConfigurationProperties for convenience.

For example, the @EnableConfigurationProperties takes the list of @ConfigurationProperty classes as input and allows the Spring container to detect and manage them as regular Spring beans.

@SpringBootApplication
@EnableConfigurationProperties(AppProperties::class)
open class ConfigurationPropertiesApplication : CommandLineRunner {
	@Autowired
	lateinit var appProperties : AppProperties

	private val logger: Logger = LoggerFactory.getLogger(ConfigurationPropertiesApplication::class.java)

	override fun run(vararg args: String?) {
		logger.info(appProperties.address)
		logger.info(appProperties.error.path)
	}
}

6. Conclusion

To sum up, we have learned to implement the Spring ConfigurationProperties using the Kotlin data class.