I'm using spring-boot
to set up spring defaults.
I'd like to use the @EnableScheduling
mechanism, and schedule my tasks conditional.
Therefore I have to implement SchedulingConfigurer
and set TaskScheduler
explicit.
But when injecting the TaskScheduler
, I get the following error. But why doesn't spring-boot automatically provide a Scheduler accordingly?
@Configuration
@EnableAutoConfiguration
@EnableScheduling
public class AppConfig {
}
@Service
public class JobService implements SchedulingConfigurer {
@Autowired
private TaskScheduler taskScheduler;
//schedule the task dynamically
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskScheduler); //fails
taskRegistrar.addTriggerTask(task, trigger);
}
}
Error:
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.scheduling.TaskScheduler; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 15 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 17 more
Run it via the Run dialog window.Press the ⊞ Win + R keyboard keys at the same time. Type taskschd. msc . Hit the ↵ Enter key or click OK.
The @EnableScheduling annotation is used to enable the scheduler for your application. This annotation should be added into the main Spring Boot application class file. The @Scheduled annotation is used to trigger the scheduler for a specific time period.
You don't need to set a scheduler on the ScheduledTaskRegistrar
. If one hasn't been configured it defaults to a ConcurrentTaskScheduler
that wraps a single-threaded scheduled executor:
if (this.taskScheduler == null) {
this.localExecutor = Executors.newSingleThreadScheduledExecutor();
this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}
If you're happy with this default scheduler you can remove your autowiring of TaskScheduler
and the call to set it on the ScheduledTaskRegistrar
. Also, as Marten's suggested in the comments, you should make your SchedulingConfigurer
a configuration class rather than a service.
These changes leave your code looking something like this:
@Configuration
static class TaskConfiguration implements SchedulingConfigurer {
//schedule the task dynamically
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(task, trigger);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With