The following is a minimal example, showing my problem.
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
is used to allow having the members of FooServiceConfig
immutable.)
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)
}
}
It works, but it only does, because I reference interval
in the @Scheduled
annotation like so:
@Scheduled(fixedDelayString = "\${configurationpropertiestest.foo.interval}")
This somewhat breaks the nicely isolated configuration of my service. It suddenly has to know about external things, which it should now need to know about.
Ideally, it would only access its configuration either by the type of the bean:
@Scheduled(fixedDelayString = "#{@FooServiceConfig.interval}")
or by the injected instance:
@Scheduled(fixedDelayString = "#{@myConfig.interval}")
But these attempts result in No bean named 'FooServiceConfig' available
and No bean named 'myConfig' available
respectively.
Any idea of how I can achieve to access only the config bean and not the global config value?