使用@Scheduled和@EnableScheduling但是给出NoSuchBeanDefinitionException

时间:2015-05-25 05:30:51

标签: java cron scheduled-tasks spring-4

我已经在线very simple examples在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工作班:

@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。我只需要每天开一次。我没有进行任何并发处理或我需要多个线程。最终这些错误是有害的还是我需要修复它们?

5 个答案:

答案 0 :(得分:18)

根据异常信息"找不到默认的TaskScheduler bean",配置应该定义" TaskScheduler"而不是"执行者"

{{1}}

}

答案 1 :(得分:16)

编辑:最佳答案是here,它涉及创建执行者:

API
interface MyIdGenerate
Server
MyIdGenerateService
MyIdGenerateProxy
MyIdGenerateXXXOperation
Client
ClientMyIdGenerateFactory
ClientMyIdGenerateProxy
MyIdGenerateXXXRequest

PREVIOUS(尽管仍然有效):

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

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

您可以通过至少设置INFO严重性来删除该例外 org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor,如

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

使用logback时。

cron表达式有六个字段:

<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>

语法可在quartz docs中找到。 我不确定&#34;?&#34;因为,虽然页面上写着

  

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

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

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

答案 2 :(得分:3)

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

<task:annotation-driven executor="myExecutor"
    scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5" />
<task:scheduler id="myScheduler" pool-size="10" />

我希望它有所帮助。

问候。

答案 3 :(得分:3)

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

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

答案 4 :(得分:2)

使用Spring Boot 2.0.5,我不断得到:

2018-11-20 11:35:48.046  INFO 64418 --- [  restartedMain] s.a.ScheduledAnnotationBeanPostProcessor : 
No TaskScheduler/ScheduledExecutorService bean found for scheduled processing

摆脱它的唯一方法似乎是在SchedulingConfigurer类中使用@Configuration接口,如下所示:

@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

注意:这取自https://www.callicoder.com/spring-boot-task-scheduling-with-scheduled-annotation/