Search code examples
javaspringspring-annotations

Spring scheduled tasks: from XML to annotation


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?


Solution

  • 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.