簡體   English   中英

Kotlin & Spring 啟動@ConfigurationProperties

[英]Kotlin & Spring Boot @ConfigurationProperties

如何在Spring Boot with Kotlin中正確初始化 ConfigurationProperties?

目前我喜歡下面的例子:

 @ConfigurationProperties("app")
 class Config {
     var foo: String? = null
 }

但它看起來很丑,實際上foo不是var ,foo 是val應該在啟動時初始化,以后不會改變

這是我如何處理我的 application.yml 文件。

myconfig:
  my-host: ssl://example.com
  my-port: 23894
  my-user: user
  my-pass: pass

這是 kotlin 文件:

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

這對我很有用。

使用新的Spring Boot 2.2,您可以這樣做:

@ConstructorBinding
@ConfigurationProperties(prefix = "swagger")
data class SwaggerProp(
    val title: String, val description: String, val version: String
)

並且不要忘記將其包含在build.gradle.kts的依賴項中:

dependencies {
  annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
}

更新:從 Spring Boot 2.2.0 開始,您可以按如下方式使用數據類:

@ConstructorBinding
@ConfigurationProperties("example.kotlin")
data class KotlinExampleProperties(
        val name: String,
        val description: String,
        val myService: MyService) {

    data class MyService(
            val apiToken: String,
            val uri: URI
    )
}

如需進一步參考,請參閱官方文檔


自 Spring Boot 2.2.0 起已過時,問題已關閉

文檔中所述:必須提供“ Java Bean ”才能使用ConfigurationProperties 。這意味着您的屬性需要具有 getter 和 setter,因此目前無法使用val

Getter 和 setter 通常是強制性的,因為綁定是通過標准的 Java Beans 屬性描述符進行的,就像在 Spring MVC 中一樣。 在某些情況下可以省略 setter [...]

Spring Boot 2.2.0 已經解決了這個問題,應該很快就會發布: https : //github.com/spring-projects/spring-boot/issues/8762

@Value("\${some.property.key:}")
lateinit var foo:String

可以這樣使用

在帶有 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)
}
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding

@ConfigurationProperties(prefix = "test")
@ConstructorBinding
data class TestProperties(
    val value: String
)

上面的代碼在暗示接下來的兩種方法之一后開始工作:

  1. 添加依賴
implementation("org.jetbrains.kotlin:kotlin-reflect")
  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
)

問題發生在 org/springframework/boot/context/properties/ConfigurationPropertiesBindConstructorProvider.java#68 行

Spring Boot 3.0 開始,您不再需要使用@ConstructorBinding注釋。

 @ConfigurationProperties("app")
 data class Config(
     val foo: String = "default foo"
 )

更多信息在這里

應用程序屬性

metro.metro2.url= ######

Metro2Config.kt

@Component
@ConfigurationProperties(prefix = "metro")
data class Metro2PropertyConfiguration(

        val metro2: Metro2 = Metro2()
)

data class Metro2(
    var url: String ?= null
)

構建.gradle

Plugins:
id 'org.jetbrains.kotlin.kapt' version '1.2.31'

// kapt dependencies required for IntelliJ auto complete of kotlin config properties class
    kapt "org.springframework.boot:spring-boot-configuration-processor"
    compile "org.springframework.boot:spring-boot-configuration-processor"

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

不要忘記添加@ConfigurationPropertiesScan

@ConfigurationPropertiesScan
class Application

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

最后是 application.properties 文件:

your.prefix.invoiceBaseDir=D:/brot-files
your.prefix.invoiceOutputFolderPdf=invoices-pdf
your.prefix.staticFileFolder=static-resources

我是這樣做的:

應用程序屬性

my.prefix.myValue=1

我的屬性.kt

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Component

@Component
@ConfigurationProperties(prefix = "my.prefix")
class MyProperties
{
    private var myValue = 0
    fun getMyValue(): Int {
        return myValue;
    }

    fun setMyValue(value: Int){
        myValue = value
    }
}

我的服務.kt

@Component
class MyService(val myProperties: MyProperties) {
    fun doIt() {
        System.console().printf(myProperties.getMyValue().toString())
    }
}

除了已經說過的內容之外,請注意val@ConstructorBinding有一些限制。 您不能將一個變量別名為另一個變量。 假設您在 Kubernetes 中運行並想要捕獲主機名,該主機名由 env var HOSTNAME 最簡單的方法是將@Value("\\${HOSTNAME}:)"應用於屬性,但它僅適用於可變屬性且沒有構造函數綁定。

請參閱帶有不可變屬性的 @ConstructorBinding 不適用於 Spring Boot Kotlin @ConfigurationProperties 中的 @Value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM