简体   繁体   中英

Should we always create a TaskExecutor bean named 'taskExecutor' when we use @EnableScheduling

I have a configuration class without explicitly bean creation method in the class:

@Configuration
@EnableAsync
@EnableScheduling
public class PollingAgent {

    @Async
    @Scheduled(fixedRate=INTERVAL_RATE, initialDelay = 10000) //setting an initial delay to let the beans get loaded
    void checkAvailableAndStartJob() {
        if(m_messageOnDemand) {
            try {
                LOGGER.info("check job messages and start job if possible");
                jobIdOnDemandSubscriber.StartJobIfMessageAvailable(m_applicationContext);
            } catch (Exception e) {
                LOGGER.info("Scheduler run failed: " + e.getMessage());
            }
        }
    }
}

But I got this log when boot run: scheduling-1: INFO org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor - More than one TaskExecutor bean found within the context, and none is named 'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly as an alias) in order to use it for async processing: [HappyMondayExecutor, taskScheduler]\n","stream":"stdout","time":"2022-08-05T20:33:41.727269489Z"}

Should I add TaskExecutor bean named 'taskExecutor' in PollingAgent ? :

@Bean
public Executor taskExecutor() {
    return Executors.newSingleThreadScheduledExecutor();
}

Why not the spring framework create a bean named 'taskExecutor' automatically when using @EnableScheduling?

Well, the info message is happening because you have more than one TaskExecutor bean declared in your application context.

From @EnableAsync javadoc:

By default, Spring will be searching for an associated thread pool definition: either a unique TaskExecutor bean in the context, or an Executor bean named "taskExecutor" otherwise. If neither of the two is resolvable, a SimpleAsyncTaskExecutor will be used to process async method invocations. Besides, annotated methods having a void return type cannot transmit any exception back to the caller. By default, such uncaught exceptions are only logged.

The log message is just an info saying "Hey, I've found two TaskExecutor declarations. Are you sure none of these was intended to be the executor for your @Async tasks?"

Anyway, as said in the quote above, a SimpleAsyncTaskExecutor bean have been designated for your @Async annotated methods executions.

Now for your question:

Why not the spring framework create a bean named 'taskExecutor' automatically when using @EnableScheduling?

Well, the @Scheduled annotated methods relies on a Scheduler. Now, a quote from @EnableScheduling javadoc :

By default, Spring will search for an associated scheduler definition: either a unique TaskScheduler bean in the context, or a TaskScheduler bean named "taskScheduler" otherwise; the same lookup will also be performed for a ScheduledExecutorService bean. If neither of the two is resolvable, a local single-threaded default scheduler will be created and used within the registrar.

Spring does not create a bean called "taskExecutor". It just creates, as said above, a local single-threaded default scheduler.

Without any task executor the below code will run. Please check which version of spring boot you are using.

@Configuration
@EnableAsync
@EnableScheduling
public class PollingAgent {
    Logger log = LoggerFactory.getLogger(PollingAgent.class);

    @Async
    @Scheduled(fixedRate=1000, initialDelay = 10000) //setting an initial delay to let the beans get loaded
    void checkAvailableAndStartJob() {
        log.info("started");
    }

   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM