使用@Scheduled和@EnableScheduling但给出NoSuchBeanDefinitionException

我已经在线跟踪非常简单的示例在Spring中设置了一个cron作业但我每次都在我的Tomcat启动日志中不断收到此错误:

2015-05-25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:191 - Could not find default TaskScheduler bean org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined 2015-05-25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:202 - Could not find default ScheduledExecutorService bean org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined 

用于实现cron的2个java类:

1)@Configuration类:

 @Configuration @EnableScheduling public class ClearTokenStoreCronEnable { final static Logger log = LoggerFactory.getLogger(ClearTokenStoreCronEnable.class); private @Autowired TokenStoreRepository tokenStoreRepository; } 

和Cron工作class:

 @Service public class ClearTokenStoreWorkerService { final static Logger log = LoggerFactory.getLogger(ClearTokenStoreWorkerService.class); private @Autowired TokenStoreRepository tokenStoreRepository; //@Scheduled(fixedDelay=5000) //run daily at midnight @Scheduled(cron = "0 0 * * * *") public void tokenStoreTable() { log.debug("tokenstore table truncated - start"); tokenStoreRepository.deleteAll(); log.debug("tokenstore table truncated - end"); } } 

作为旁注,cron作业在午夜运行,但它似乎也在其他时间随机运行。 不确定这是一个错误还是我的cron表达式错误: @Scheduled(cron = "0 0 * * * *")

我此时主要担心的是为什么我会收到ScheduledAnnotationBeanPostProcessor错误? 它正在寻找TaskScheduler和ScheduledExectorService。 我只需要每天开一次。 我没有进行任何并发处理或我需要多个线程。 最终这些错误是有害的还是我需要修复它们?

编辑:最好的答案在这里 ,它涉及创建一个执行器:

 @Configuration @EnableAsync public class AppContext extends WebMvcConfigurationSupport { @Bean public Executor taskExecutor() { return new SimpleAsyncTaskExecutor(); } } 

上一个(尽管仍然有效):

使用DEBUG严重性记录NoSuchBeanDefinitionException,可以安全地忽略它。 如果查看ScheduledAnnotationBeanPostProcessor的源代码,您会看到它首先尝试获取TaskScheduler,然后是ScheduledExecutorService,然后它继续“回退到默认调度程序”:

  if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) { Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type"); try { // Search for TaskScheduler bean... this.registrar.setScheduler(this.beanFactory.getBean(TaskScheduler.class)); } catch (NoUniqueBeanDefinitionException ex) { throw new IllegalStateException("More than one TaskScheduler exists within the context. " + "Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " + "ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex); } catch (NoSuchBeanDefinitionException ex) { logger.debug("Could not find default TaskScheduler bean", ex); // Search for ScheduledExecutorService bean next... try { this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class)); } catch (NoUniqueBeanDefinitionException ex2) { throw new IllegalStateException("More than one ScheduledExecutorService exists within the context. " + "Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " + "ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex); } catch (NoSuchBeanDefinitionException ex2) { logger.debug("Could not find default ScheduledExecutorService bean", ex); // Giving up -> falling back to default scheduler within the registrar... } } } 

您可以通过在org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor上设置至少一个INFO严重性来删除exception,如

  

使用logback时。

cron表达式有六个字段:

 second (0-59), minute (0-59), hour (0-23, 0 = midnight), day (1-31), month (1-12), weekday (1-7, 1 = Sunday) 

语法可以在quartz文档中找到。 我不确定“?” 因为,虽然页面说

‘?’ 允许使用字符表示日期和星期几字段。 它用于指定“无特定值”。 当您需要在两个字段之一中指定某些内容而不是另一个字段时,这非常有用。

该页面上的示例实际使用? 即使其他领域是*。 恕我直言所有应该只使用*,所以为了每个午夜执行,表达式应该是

 0 0 0 * * * 

根据exception信息“无法找到默认的TaskScheduler bean”,配置应该定义“TaskScheduler”而不是“Executor”

 @Configuration public class AppContext extends WebMvcConfigurationSupport { @Bean public TaskScheduler taskScheduler() { return new ConcurrentTaskScheduler(); } // Of course , you can define the Executor too @Bean public Executor taskExecutor() { return new SimpleAsyncTaskExecutor(); } 

}

我同意你可以忽略它,但只是改变严重性不会解决它。 我有同样的问题,但我使用xml而不是注释,在我的情况下,它发生,因为我没有在我的bean定义中包含执行程序。 所以添加这个修复它:

    

我希望它有所帮助。

问候。

要解决此问题,只需在config中创建任务调度程序bean。

 @Bean public TaskScheduler taskScheduler() { return new ConcurrentTaskScheduler(); }