Ниже приведен минимальный пример, показывающий мою проблему.
Main.kt
:
package com.mycompany.configurationpropertiestest
import org.slf4j.LoggerFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Service
@SpringBootApplication
@EnableScheduling
@EnableConfigurationProperties(FooServiceConfig::class)
class Application
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
@ConstructorBinding
@ConfigurationProperties("configurationpropertiestest.foo")
data class FooServiceConfig(
val interval: Int = 1000,
val message: String = "hi"
)
@Service
class FooService(
private val myConfig: FooServiceConfig
) {
private val log = LoggerFactory.getLogger(this.javaClass)
//@Scheduled(fixedDelayString = "#{@FooServiceConfig.interval}")
//@Scheduled(fixedDelayString = "#{@myConfig.interval}")
@Scheduled(fixedDelayString = "\${configurationpropertiestest.foo.interval}")
fun talk() {
log.info(myConfig.message)
}
}
(@ConstructorBinding
используется для разрешения неизменности членов FooServiceConfig
. )
application.yml
:
configurationpropertiestest:
foo:
interval: 500
message: "hi"
Test.kt
:
package com.mycompany.configurationpropertiestest
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringRunner
@RunWith(SpringRunner::class)
@SpringBootTest
class Test {
@Test
fun `sit and wait`() {
Thread.sleep(3000)
}
}
Это работает, но работает только потому, что я ссылаюсь interval
в @Scheduled
аннотация примерно такая:
@Scheduled(fixedDelayString = "\${configurationpropertiestest.foo.interval}")
Это несколько нарушает красиво изолированную конфигурацию моего сервиса. Внезапно он должен знать о внешних вещах, о которых он должен теперь знать.
В идеале он должен был бы получить доступ к своей конфигурации либо по типу компонента:
@Scheduled(fixedDelayString = "#{@FooServiceConfig.interval}")
или с помощью внедренного экземпляра:
@Scheduled(fixedDelayString = "#{@myConfig.interval}")
Но эти попытки приводят к No bean named 'FooServiceConfig' available
и No bean named 'myConfig' available
соответственно.
Любая идея о том, как я могу получить доступ только к бину конфигурации, а не к значение глобальной конфигурации?