I have a final config-class like this:
@Value // <- lombok-annotation
@ConstructorBinding
@ConfigurationProperties("my-app.conf")
public class MyProperties {
Duration reloadPeriod;
}
And I want to use the reloadPeriod
in a @Scheduled
field like this:
@Service
public class MyService {
@Scheduled(fixedDelayString = "#{myProperties.reloadPeriod}")
public void doSomeRecurrentStuff() {
// some work
}
}
But this setup will always fail with this error:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'myProperties' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
When I add an "intermediate bean" like this:
@Configuration
public class MyConfigClass {
@Bean("reloadPeriod")
Duration reloadPeriod(MyProperties props) {
return props.getReloadPeriod();
}
}
then I can reference it without any problems like this: @Scheduled(fixedDelayString = "#{reloadPeriod}")
How can I access "like beans" created by @ConstructorBinding
via SpEL?
You can use beanFactory
to get the configuration properties bean by its type.
@Scheduled(fixedDelayString =
"#{beanFactory.getBean(T(com.package.MyProperties)).reloadPeriod}")
public void doSomeRecurrentStuff() {
// ...
}
Alternatively, implement SchedulingConfigurer
to programmatically set up scheduled tasks.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
@Autowired
private MyProperties myProperties;
void doSomeRecurrentStuff() {
// some work
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addFixedDelayTask(this::doSomeRecurrentStuff,
myProperties.getReloadPeriod());
}
}