使用@Scheduled和@EnableScheduling但给出NoSuchBeanDefinitionException [英] Using @Scheduled and @EnableScheduling but gives NoSuchBeanDefinitionException

查看:9061
本文介绍了使用@Scheduled和@EnableScheduling但给出NoSuchBeanDefinitionException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已按照非常简单的示例在线设置我在Tomcat启动日志中每次都遇到这个错误:

  2015-05- 25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:191  -  
无法找到默认TaskScheduler bean org.springframework.beans.factory.NoSuchBeanDefinitionException:No
限定类型为[org.springframework.scheduling.TaskScheduler]的bean是定义

2015-05-25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:202 - 不能
查找默认ScheduledExecutorService bean
org.springframework.beans.factory.NoSuchBeanDefinitionException:无限定
定义类型为[org.springframework.scheduling.TaskScheduler]的bean

用于实现cron的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)
//每天在午夜运行
@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。我只需要每天发射一次。我不做任何并发处理或我需要多个线程。

解决方案

编辑:最好的答案是这里,它涉及创建一个Executor:

  @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必须设置为按类型查找调度程序);
try {
//搜索TaskScheduler bean ...
this.registrar.setScheduler(this.beanFactory.getBean(TaskScheduler.class));
}
catch(NoUniqueBeanDefinitionException ex){
throw new IllegalStateException(上下文中存在多个TaskScheduler+
除去一个bean, SchedulingConfigurer接口和调用+
ScheduledTaskRegistrar#setScheduler显式地在configureTasks()回调。
}
catch(NoSuchBeanDefinitionException ex){
logger.debug(Could not find default TaskScheduler bean,ex);
//搜索ScheduledExecutorService bean接下来...
try {
this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class));
}
catch(NoUniqueBeanDefinitionException ex2){
throw new IllegalStateException(上下文中存在多个ScheduledExecutorService)+
除去所有bean, SchedulingConfigurer接口和调用+
ScheduledTaskRegistrar#setScheduler显式地在configureTasks()回调。
}
catch(NoSuchBeanDefinitionException ex2){
logger.debug(Could not find default ScheduledExecutorService bean,ex);
//放弃 - >回到默认调度程序在注册表中...
}
}
}

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

 < logger name =org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessorlevel =INFO/> 


$ b 表达式有六个字段:

 秒(0-59),分(0-59) = midnight),day(1-31),month(1-12),weekday(1-7,1 = Sunday)

语法可以在石英文档
我不知道?字符,因为虽然页面上显示


字符?可用于日期和星期字段。它用于指定无特定值。当您需要在两个字段中的一个中指定某个内容时,此选项非常有用。


使用 ?即使其他字段是*。
IMHO都应该只使用*,所以为了每个午夜执行,表达式应该是

  0 0 0 * * * 


I have followed very simple examples online to set up a cron job in Spring yet I keep getting this error in my Tomcat startup log each and every time:

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

And the 2 java classes used to implement the cron:

1) The @Configuration class:

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

and Cron job 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");
    }
}

As a side note, the cron job runs at midnight but it also seems to run randomly at other times. Not sure if this is a bug or my cron expression is wrong: @Scheduled(cron = "0 0 * * * *")

My main concern at this time is why am I getting ScheduledAnnotationBeanPostProcessor errors? It's looking for a TaskScheduler and ScheduledExectorService. I just need to fire this once a day. I am not doing any concurrent processing or where I need multiple threads. Ultimately are these errors harmful OR do I need to fix them?

解决方案

EDIT: the best answer is here and it involves creating an Executor:

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

PREVIOUS (still valid though):

The NoSuchBeanDefinitionException is logged with a DEBUG severity and can be safely ignored. If you look at the source code for ScheduledAnnotationBeanPostProcessor, you see that it first tries to get a TaskScheduler, then a ScheduledExecutorService, then it keeps going on "falling back to default scheduler":

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

You can remove the exception by setting at least a INFO severity on org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor, like

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

when using logback.

The cron expression has six fields:

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

The syntax can be found in the quartz docs. I'm not sure about the "?" character because, although the page says

The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify "no specific value". This is useful when you need to specify something in one of the two fields, but not the other.

the examples on that page actually use ? even when the other field is *. IMHO all should work with just *, so in order to execute every midnight, the expression should be

0 0 0 * * *

这篇关于使用@Scheduled和@EnableScheduling但给出NoSuchBeanDefinitionException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆