Issue
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?
Solution
Well, the info message is happening because you have more than one TaskExecutor
bean declared in your application context.
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.
Answered By - Matheus Cirillo
Answer Checked By - Robin (JavaFixing Admin)