Kotlin Micronaut未加载application.yml属性。

huangapple go评论93阅读模式
英文:

Kotlin Micronaut is not loading application.yml properties

问题

以下是您提供的代码部分的翻译:

  1. // SftpConfig.kt
  2. @ConfigurationProperties("sftp")
  3. class SftpConfig {
  4. var knownHostFile: String = FileConverterConstant.SFTP_KNOWN_HOSTS_FILE_PATH
  5. var privateKeyFile: String = FileConverterConstant.SFTP_PRIVATE_KEY_PATH
  6. var privateKeyPass: CharArray = FileConverterConstant.SFTP_PRIVATE_KEY_PASS.toCharArray()
  7. @NotBlank
  8. lateinit var username: String
  9. @NotBlank
  10. lateinit var remoteHost: String
  11. var remotePort: Int = FileConverterConstant.SFTP_REMOTE_PORT
  12. var verifyTimeout: Long = FileConverterConstant.SFTP_VERIFY_TIMEOUT
  13. }
  1. // 在测试函数内
  2. "测试" {
  3. val items: MutableMap<String, Any> = HashMap()
  4. items["sftp.username"] = "test"
  5. items["sftp.remoteHost"] = "1.0.0.0"
  6. val ctx = ApplicationContext.run(items)
  7. val sftpConfig = ctx.getBean(SftpConfig::class.java)
  8. println(sftpConfig.username)
  9. }
  1. // 使用 @Inject 创建 bean 并尝试使用 bean
  2. @Inject
  3. 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

  1. micronaut:
  2. application:
  3. name: sftp-test
  4. netty:
  5. default:
  6. allocator:
  7. max-order: 3
  8. sftp:
  9. known-hosts-file: &quot;testKnownHost&quot;
  10. private-key-file: &quot;testPk&quot;
  11. username: &quot;testUser&quot;
  12. password:
  13. remote-host: &quot;1.0.0.0&quot;
  14. remote-port: 22
  15. verify-timeout: 20000
  1. // SftpConfig.kt
  2. @ConfigurationProperties(&quot;sftp&quot;)
  3. class SftpConfig {
  4. var knownHostFile: String = FileConverterConstant.SFTP_KNOWN_HOSTS_FILE_PATH
  5. var privateKeyFile: String = FileConverterConstant.SFTP_PRIVATE_KEY_PATH
  6. var privateKeyPass: CharArray = FileConverterConstant.SFTP_PRIVATE_KEY_PASS.toCharArray()
  7. @NotBlank
  8. lateinit var username: String
  9. @NotBlank
  10. lateinit var remoteHost: String
  11. var remotePort: Int = FileConverterConstant.SFTP_REMOTE_PORT
  12. var verifyTimeout: Long = FileConverterConstant.SFTP_VERIFY_TIMEOUT
  13. }
  1. // Inside a test function
  2. &quot;Test&quot; {
  3. val items: MutableMap&lt;String, Any&gt; = HashMap()
  4. items[&quot;sftp.username&quot;] = &quot;test&quot;
  5. items[&quot;sftp.remoteHost&quot;] = &quot;1.0.0.0&quot;
  6. val ctx = ApplicationContext.run(items)
  7. val sftpConfig = ctx.getBean(SftpConfig::class.java)
  8. println(sftpConfig.username)
  9. }

If I remove the properties from the items map for example items[&quot;sftp.username&quot;] = &quot;test&quot;, 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

  1. @Inject
  2. 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。

  1. import io.kotest.assertions.assertSoftly
  2. import io.kotest.core.spec.style.BehaviorSpec
  3. import io.kotest.matchers.string.shouldNotBeEmpty
  4. import io.micronaut.test.extensions.kotest5.annotation.MicronautTest
  5. @MicronautTest
  6. class SftpConfigPropertiesTest(sut: SftpConfig) : BehaviorSpec({
  7. Given("在application.yml中填充了SFTP配置") {
  8. Then("所有字段应该填充") {
  9. assertSoftly(sut){
  10. it.username.shouldNotBeEmpty()
  11. /** 添加剩下的断言 */
  12. }
  13. }
  14. }
  15. })

我认为最佳实践是使用构造函数注入,而不是 @Inject。示例:

  1. @Singleton
  2. class MyService(private val sftpConfig: SftpConfig) {
  3. /** 类体部分在这里 */
  4. }
英文:

For testing your config, you should use @MicronautTest and inject the config-DTO like shown below.

  1. import io.kotest.assertions.assertSoftly
  2. import io.kotest.core.spec.style.BehaviorSpec
  3. import io.kotest.matchers.string.shouldNotBeEmpty
  4. import io.micronaut.test.extensions.kotest5.annotation.MicronautTest
  5. @MicronautTest
  6. class SftpConfigPropertiesTest(sut: SftpConfig) : BehaviorSpec({
  7. Given(&quot;populated sftp in application.yml&quot;) {
  8. Then(&quot;all fields should be populated&quot;) {
  9. assertSoftly(sut){
  10. it.username.shouldNotBeEmpty()
  11. /** add remaining assertions */
  12. }
  13. }
  14. }
  15. })

I believe best practice is to use constructor injection instead of @Inject. Example:

  1. @Singleton
  2. class MyService(private val sftpConfig : SftpConfig) {
  3. /** class body goes here */
  4. }

huangapple
  • 本文由 发表于 2023年3月4日 04:46:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75631728.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定