Is there a more succinct way to initialize propert...
# spring
h
Is there a more succinct way to initialize properties of a configuration from a properties file than this?
Copy code
@Configuration
class FooConfiguration {
    @Value("\${foo.bar}")
    lateinit var bar: String
}
This just seems really verbose, even compared to the java way, and I tend to prefer lazy delegation val over lateinit var for immutable properties like this.
d
starting with SpringBoot 2.2
Copy code
@ConstructorBinding
@Configuration("foo")
class FooConfiguration(val bar: String)
💯 2
h
try as i might, i just cannot get this to work... a shame as that syntax is so much better
d
do you also have
Copy code
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>${spring-boot.version}</version>
            <optional>true</optional>
        </dependency>
in your deps?
h
i'm using gradle:
Copy code
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    val kotlinVersion = "1.3.50"
    idea
    kotlin("jvm") version kotlinVersion
    kotlin("plugin.spring") version kotlinVersion
    kotlin("kapt") version kotlinVersion
    id("org.springframework.boot") version "2.2.0.RELEASE"
    id("io.spring.dependency-management") version "1.0.8.RELEASE"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    implementation(kotlin("reflect"))
    kapt("org.springframework.boot", "spring-boot-configuration-processor")
    implementation("org.springframework.boot", "spring-boot-configuration-processor")
    implementation("org.springframework.boot", "spring-boot-starter-web")
    implementation("org.springframework.security.oauth.boot", "spring-security-oauth2-autoconfigure", "2.2.0.RELEASE")
    implementation("org.springframework.boot", "spring-boot-starter-data-mongodb")
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}
so yes, and using kapt
h
reading
I get
Copy code
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resource-server': @EnableConfigurationProperties or @ConfigurationPropertiesScan must be used to add @ConstructorBinding type src.config.ResourceServerConfiguration
when
@EnableConfigurationProperties
is literally right there in the code:
Copy code
@EnableResourceServer
@EnableConfigurationProperties
@ConstructorBinding
@Configuration("resource-server")
class ResourceServerConfiguration(val resourceId: String) : ResourceServerConfigurerAdapter()
d
have you tried
@EnableConfigurationProperties(FooConfiguration::class)
?
thats how we got it configured
ah shouldnt
@EnableConfigurationProperties
be on other
@Configuration
class?
h
tried moving the annotation everywhere. i don't get this issue when i use the
lateinit var
syntax
it might be an intellij thing
d
no idea,
@ConstructorBinding
is new thing so maybe it is pretty finicky 🤷
h
durn. alright. nbd. hopefully 2.2.1 will fix the issue 😛
j
I also tried & failed to get it to work.
h
I got it to work using
Copy code
@ConstructorBinding
@ConfigurationProperties("foo")
class FooConfiguration(val bar: String)
@Dariusz Kuc
d
👍
h
I think it could be improved by interpreting the property name from the class name just as it does from the names of the class fields. Also, then potentially the
@ConfigurationProperties
annotation would be superfluous and it could simply read:
Copy code
@ConstructorBinding data class Foo(val bar: String, val baz: String)
d
it actually originally (in RCs) didn't need extra
@ConstructorBinding
annotation 🙂 unsure why pivotal decided to add that requirement in
h
yeah i could see how simply using the
@configuration
annotation should be able to realize which constructor arguments are autowired, and which are properties by checking the former then the latter
or having plugins or something like lombok so that you don't even have to redeclare the properties in your code. you can access them automatically if they're in the application.properties/yml file under the right property name
even though this is perfectly fine and working code, in intellij
@ConfigurationProperties
is highlighted as an error saying that this class is not designated as a component. if I add that annotation, everything still works fine, but then
id
is highlighted as an error saying there are no
String
beans. Calling wolf here is part of the reason I had such a hard time with it.
Copy code
@EnableResourceServer
@ConstructorBinding
@ConfigurationProperties("resource-server")
class ResourceServerConfiguration(private val id: String) : ResourceServerConfigurerAdapter()
Also the "Re-run Spring Boot Annotation Processor to update generated metadata" banner message is annoying and should be addressed.