In our Spring web-application, we are moving from XML based configuration to Annotation based configuration.
I'm stuck with a scheduled task defined with this XML
<task:scheduled-tasks scheduler="cacheScheduler">
<task:scheduled ref="currencyExchangeRateTask" method="cacheCurrencyExchangeRates" cron="0 0 8,20 * * *" />
</task:scheduled-tasks>
There are multiple schedulers in our web-application. And this task needs to be executed on the scheduler with id cacheScheduler
.
I have now the following annotation in place
@Scheduled(cron = "0 0 8,20 * * *")
public void cacheCurrencyExchangeRates() {
...
}
This is executing on the default scheduler.
How can this be fixed without XML configuration?
You can't do it through @Scheduled
directly. It doesn't provide any annotation members to specify a bean reference name.
Instead, you have to use SchedulingConfigurer
. Define a @Configuration
class. Annotate it with @EnableScheduling
and @ComponentScan
for the packages with component types that have @Scheduled
annotated methods. Then have the class implement SchedulingConfigurer
.
The ScheduledTaskRegistrar
provided through its configureTasks
method lets you set a task scheduler.
For example:
@Configuration
@ComponentScan("com.example.tasks")
@EnableScheduling
class Tasks implements SchedulingConfigurer {
@Bean
public TaskScheduler cacheScheduler() {
return new ThreadPoolTaskScheduler();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(cacheScheduler());
}
}
All the @Scheduled
methods discovered through this @Configuration
class will now be using the TaskScheduler
defined within.
If you need different @Scheduled
methods to use different TaskScheduler
instances, you'll need different @Configuration
classes, similarly to needing different <task:scheduled-tasks .../>
elements.