web-dev-qa-db-ja.com

@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
_

そして、2 Java cronの実装に使用されるクラス:

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を探しています。これを1日に1回実行するだけです。並行処理を行っていません。または、複数のスレッドが必要です。最終的に、これらのエラーは有害ですOR修正する必要がありますか?

23
logixplayer

例外情報「デフォルトのTaskScheduler Beanが見つかりませんでした」によると、構成は「Executor」ではなく「TaskScheduler」を定義する必要があります

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

}

18
randy

編集:ベストアンサーは here であり、エグゼキューターの作成が含まれます:

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

前(まだ有効):

NoSuchBeanDefinitionExceptionは重大度DEBUGでログに記録されるため、無視しても問題ありません。 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重大度を設定することにより、例外を削除できます。

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

ログバックを使用する場合。

Cron式には6つのフィールドがあります。

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

構文は quartz docs にあります。 「?」がわからないなぜなら、ページには

「?」文字は、曜日と曜日のフィールドに使用できます。 「特定の値なし」を指定するために使用されます。これは、2つのフィールドのいずれかで何かを指定する必要があるが、他のフィールドでは指定しない場合に役立ちます。

そのページの例は実際に使用していますか?他のフィールドが*であっても。私見はすべて*だけで動作するはずなので、真夜中ごとに実行するには、式は

0 0 0 * * *
16
xtian

この問題を解決するには、configでタスクスケジューラBeanを作成します。

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

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

これを取り除く唯一の方法は、@ConfigurationクラスでSchedulingConfigurerインターフェイスを次のように使用することです。

@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/ から取得されました

3
Wim Deblauwe

私はあなたがそれを無視できることに同意しますが、重大度を変更するだけでは修正されません。私は同じ問題を抱えていましたが、注釈の代わりにxmlを使用しています。私の場合、Bean定義にexecutorを含めなかったために起こりました。これを追加すると修正されました:

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

役に立てば幸いです。

よろしく。

3
Eduardo G