Java 如何在 spring-boot 中启用 TaskScheduler?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28452400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 06:15:45  来源:igfitidea点击:

How to enable TaskScheduler in spring-boot?

javaspringspring-bootspring-scheduled

提问by membersound

I'm using spring-bootto set up spring defaults. I'd like to use the @EnableSchedulingmechanism, and schedule my tasks conditional.

我正在使用spring-boot设置弹簧默认值。我想使用该@EnableScheduling机制,并有条件地安排我的任务。

Therefore I have to implement SchedulingConfigurerand set TaskSchedulerexplicit.

因此我必须实现SchedulingConfigurerTaskScheduler明确设置。

But when injecting the TaskScheduler, I get the following error. But why doesn't spring-boot automatically provide a Scheduler accordingly?

但是在注入 时TaskScheduler,我收到以下错误。但是为什么 spring-boot 不相应地自动提供调度程序?

@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

采纳答案by Andy Wilkinson

You don't need to set a scheduler on the ScheduledTaskRegistrar. If one hasn't been configured it defaults to a ConcurrentTaskSchedulerthat wraps a single-threaded scheduled executor:

您不需要在ScheduledTaskRegistrar. 如果尚未配置,则默认为ConcurrentTaskScheduler包装单线程调度执行程序的一个:

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 TaskSchedulerand the call to set it on the ScheduledTaskRegistrar. Also, as Marten's suggested in the comments, you should make your SchedulingConfigurera configuration class rather than a service.

如果您对这个默认调度程序感到满意,您可以删除您的自动装配TaskScheduler和在ScheduledTaskRegistrar. 此外,正如 Marten 在评论中所建议的那样,您应该将您SchedulingConfigurer的配置类设置为配置类而不是服务。

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