web-dev-qa-db-ja.com

Spring-BootでTaskSchedulerを有効にする方法は?

spring-bootを使用して春のデフォルトを設定しています。 @EnableSchedulingメカニズムを使用して、タスクを条件付きでスケジュールしたいと思います。

したがって、SchedulingConfigurerを実装し、TaskSchedulerを明示的に設定する必要があります。

しかし、TaskSchedulerを挿入すると、次のエラーが発生します。しかし、なぜスプリングブートはそれに応じてスケジューラーを自動的に提供しないのですか?

@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);
    }
}

エラー:

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
7
membersound

ScheduledTaskRegistrarにスケジューラを設定する必要はありません。構成されていない場合は、デフォルトでConcurrentTaskSchedulerに設定され、シングルスレッドのスケジュールされたエグゼキューターがラップされます。

if (this.taskScheduler == null) {
    this.localExecutor = Executors.newSingleThreadScheduledExecutor();
    this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
}

このデフォルトのスケジューラーに満足している場合は、TaskSchedulerの自動配線とそれをScheduledTaskRegistrarに設定するための呼び出しを削除できます。また、Martenがコメントで示唆しているように、SchedulingConfigurerをサービスではなく構成クラスにする必要があります。

これらの変更により、コードは次のようになります。

@Configuration
static class TaskConfiguration implements SchedulingConfigurer {

    //schedule the task dynamically
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addTriggerTask(task, trigger);
    }
}
8
Andy Wilkinson