英文:
Kotlin Micronaut is not loading application.yml properties
问题
以下是您提供的代码部分的翻译:
// SftpConfig.kt
@ConfigurationProperties("sftp")
class SftpConfig {
var knownHostFile: String = FileConverterConstant.SFTP_KNOWN_HOSTS_FILE_PATH
var privateKeyFile: String = FileConverterConstant.SFTP_PRIVATE_KEY_PATH
var privateKeyPass: CharArray = FileConverterConstant.SFTP_PRIVATE_KEY_PASS.toCharArray()
@NotBlank
lateinit var username: String
@NotBlank
lateinit var remoteHost: String
var remotePort: Int = FileConverterConstant.SFTP_REMOTE_PORT
var verifyTimeout: Long = FileConverterConstant.SFTP_VERIFY_TIMEOUT
}
// 在测试函数内
"测试" {
val items: MutableMap<String, Any> = HashMap()
items["sftp.username"] = "test"
items["sftp.remoteHost"] = "1.0.0.0"
val ctx = ApplicationContext.run(items)
val sftpConfig = ctx.getBean(SftpConfig::class.java)
println(sftpConfig.username)
}
// 使用 @Inject 创建 bean 并尝试使用 bean
@Inject
val sftpConfig = SftpConfig()
关于您的问题,这是有关Micronaut应用程序配置的内容,您是否需要任何进一步的帮助?
英文:
After following 5. Team Configuration with @ConfigurationProperties
in this document https://guides.micronaut.io/latest/micronaut-configuration-maven-kotlin.html. And created a configuration bean like this
micronaut:
application:
name: sftp-test
netty:
default:
allocator:
max-order: 3
sftp:
known-hosts-file: "testKnownHost"
private-key-file: "testPk"
username: "testUser"
password:
remote-host: "1.0.0.0"
remote-port: 22
verify-timeout: 20000
// SftpConfig.kt
@ConfigurationProperties("sftp")
class SftpConfig {
var knownHostFile: String = FileConverterConstant.SFTP_KNOWN_HOSTS_FILE_PATH
var privateKeyFile: String = FileConverterConstant.SFTP_PRIVATE_KEY_PATH
var privateKeyPass: CharArray = FileConverterConstant.SFTP_PRIVATE_KEY_PASS.toCharArray()
@NotBlank
lateinit var username: String
@NotBlank
lateinit var remoteHost: String
var remotePort: Int = FileConverterConstant.SFTP_REMOTE_PORT
var verifyTimeout: Long = FileConverterConstant.SFTP_VERIFY_TIMEOUT
}
// Inside a test function
"Test" {
val items: MutableMap<String, Any> = HashMap()
items["sftp.username"] = "test"
items["sftp.remoteHost"] = "1.0.0.0"
val ctx = ApplicationContext.run(items)
val sftpConfig = ctx.getBean(SftpConfig::class.java)
println(sftpConfig.username)
}
If I remove the properties from the items map for example items["sftp.username"] = "test"
, the missing properties was filled with the properties from the application.yml file I configured. Everything seems to be working in the test like this page documented.
So now I moved this to an Singleton bean class
When I use @Inject
like below to create the bean and try to use the bean. It wont read anything from the application.ym
@Inject
val sftpConfig = SftpConfig()
Now it gives me this error message Message: lateinit property username has not been initialized
If I allow the filed to be null. It is null after calling the bean. So the values in application.yml file is not being loaded at all.
While in the test the ApplicationContext was manually created, in here I am relying on Micronaut, am I missing certain dependency? What could be the reason the values in application.yml is not loaded? Side note, if I assign a health endpoint in the application.yml file, it does work after server starts. So the file is being read, but the values I configured for sftp is not being injected in to the configuration bean.
答案1
得分: 1
在测试配置时,您应该使用 @MicronautTest
并像下面所示注入配置-DTO。
import io.kotest.assertions.assertSoftly
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.string.shouldNotBeEmpty
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest
@MicronautTest
class SftpConfigPropertiesTest(sut: SftpConfig) : BehaviorSpec({
Given("在application.yml中填充了SFTP配置") {
Then("所有字段应该填充") {
assertSoftly(sut){
it.username.shouldNotBeEmpty()
/** 添加剩下的断言 */
}
}
}
})
我认为最佳实践是使用构造函数注入,而不是 @Inject
。示例:
@Singleton
class MyService(private val sftpConfig: SftpConfig) {
/** 类体部分在这里 */
}
英文:
For testing your config, you should use @MicronautTest
and inject the config-DTO like shown below.
import io.kotest.assertions.assertSoftly
import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.string.shouldNotBeEmpty
import io.micronaut.test.extensions.kotest5.annotation.MicronautTest
@MicronautTest
class SftpConfigPropertiesTest(sut: SftpConfig) : BehaviorSpec({
Given("populated sftp in application.yml") {
Then("all fields should be populated") {
assertSoftly(sut){
it.username.shouldNotBeEmpty()
/** add remaining assertions */
}
}
}
})
I believe best practice is to use constructor injection instead of @Inject
. Example:
@Singleton
class MyService(private val sftpConfig : SftpConfig) {
/** class body goes here */
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论