Kotlin和Spring Boot @ConfigurationProperties

Son*_*que 33 spring kotlin spring-boot

如何使用KotlinSpring Boot中正确初始化ConfigurationProperties ?

目前我喜欢以下示例:

 @ConfigurationProperties("app")
 class Config {
     var foo: String? = null
 }
Run Code Online (Sandbox Code Playgroud)

但它看起来很丑陋,实际上foo并不是一个var可行的,foo是不变的 val,应该在启动时初始化,并且将来不会改变.

Ray*_*ter 38

以下是我使用application.yml文件的方法.

myconfig:
  my-host: ssl://example.com
  my-port: 23894
  my-user: user
  my-pass: pass
Run Code Online (Sandbox Code Playgroud)

这是kotlin文件:

@Configuration
@ConfigurationProperties(prefix = "myconfig")
class MqttProperties {
    lateinit var myHost: String
    lateinit var myPort: String
    lateinit var myUser: String
    lateinit var myPass: String    
}
Run Code Online (Sandbox Code Playgroud)

这对我很有用.

  • 原始类型怎么样,因为它们不允许"lateinit"? (6认同)
  • `var myPort:Long = 23894`会起作用 (3认同)
  • 经过一些研究,这似乎是最合理的选择.它避免重复使用有点脏的@Value注释,并且还将确保在属性文件中设置配置(如果缺少相关的配置条目,则抛出不初始化值的异常). (2认同)
  • 如果环境中不存在任何后期初始化属性,会发生什么情况 - 您是否会遇到运行时空指针异常? (2认同)

Vla*_*tem 11

在带有 Kotlin 1.4.3 的 Spring Boot 2.4.3 上,下一个方法不再有效(可能是因为错误):

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.EnableConfigurationProperties

@SpringBootApplication
@EnableConfigurationProperties(TestProperties::class)
class Application

fun main(args: Array<String>) {
    runApplication<Application>(*args)
}
Run Code Online (Sandbox Code Playgroud)
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding

@ConfigurationProperties(prefix = "test")
@ConstructorBinding
data class TestProperties(
    val value: String
)
Run Code Online (Sandbox Code Playgroud)

上面的代码在暗示接下来两种方法之一后开始工作:

  1. 添加依赖项
implementation("org.jetbrains.kotlin:kotlin-reflect")
Run Code Online (Sandbox Code Playgroud)
  1. 更新属性类
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding

@ConfigurationProperties(prefix = "test")
data class TestProperties @ConstructorBinding constructor(
    val value: String
)
Run Code Online (Sandbox Code Playgroud)

问题发生在 org/springframework/boot/context/properties/ConfigurationPropertiesBindConstructorProvider.java#68 行


s1m*_*nw1 10

正如文档中所述:必须提供" Java Bean "才能使用ConfigurationProperties.这意味着您的属性需要具有getter和setter,因此val目前无法实现.

getter和setter通常是必需的,因为绑定是通过标准的Java Beans属性描述符,就像在Spring MVC中一样.有些情况下可能会省略一个二传手[...]

虽然有一个与Kotlin相关的开放性问题:https://github.com/spring-projects/spring-boot/issues/8762

  • 您能否举例说明给定代码示例的 application.properties 文件应是什么样子?我遇到了类似的情况,我不确定如何将值传递给具有多个参数的构造函数。 (2认同)

Dmi*_*ich 8

使用新的Spring Boot 2.2,您可以这样:

@ConstructorBinding
@ConfigurationProperties(prefix = "swagger")
data class SwaggerProp(
    val title: String, val description: String, val version: String
)
Run Code Online (Sandbox Code Playgroud)

并且不要忘记在依赖项中包含此内容build.gradle.kts

dependencies {
  annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
}
Run Code Online (Sandbox Code Playgroud)

  • 据我了解,kapt 已经取代了annotationProcessor。您可以使用 Kotlin 1.3.50+ 和 `plugins { ... kotlin("kapt") }` 和 `kapt(...)` 来包装依赖项字符串,而不是 `annotationProcessor(...)` (6认同)

mle*_*ter 7

@ConstructorBinding
@ConfigurationProperties(prefix = "your.prefix")
data class AppProperties (
    val invoiceBaseDir: String,
    val invoiceOutputFolderPdf: String,
    val staticFileFolder: String
)
Run Code Online (Sandbox Code Playgroud)

不要忘记添加@ConfigurationPropertiesScan

@ConfigurationPropertiesScan
class Application

fun main(args: Array<String>) {
    runApplication<Application>(*args)
}
Run Code Online (Sandbox Code Playgroud)

最后是 application.properties 文件:

your.prefix.invoiceBaseDir=D:/brot-files
your.prefix.invoiceOutputFolderPdf=invoices-pdf
your.prefix.staticFileFolder=static-resources
Run Code Online (Sandbox Code Playgroud)


Sta*_*avL 6

@Value("\${some.property.key:}")
lateinit var foo:String
Run Code Online (Sandbox Code Playgroud)

可以这样用

  • 谢谢你的评论。我知道`@Value`注释,但我不考虑这种方式,因为它会产生很多样板代码,`@ConfigurationProperties`肯定更好。 (6认同)

pix*_*xel 6

Spring Boot 3.0开始,如果您有一个构造函数,则不再需要使用@ConstructorBinding注释。

 @ConfigurationProperties("app")
 data class Config(
     val foo: String = "default foo"
 )
Run Code Online (Sandbox Code Playgroud)

更多信息在这里