TaskExecutor and TaskScheduler being picked up by Spring as same type
java, spring
Solution
This `@Bean` method
@Bean
public TaskScheduler taskScheduler() {
returns an object of type `ThreadPoolTaskScheduler` which is
public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
implements TaskScheduler, SchedulingTaskExecutor {
so it fits both interfaces, `TaskScheduler` and `TaskExecutor` (super type of `SchedulingTaskExecutor`).
If you try to inject a field of type `TaskExecutor` like your stack trace says
Could not autowire field: private org.springframework.core.task.TaskExecutor...
Spring won't be able to choose which one.
This will only happen if the `ApplicationContext` from where you are trying to pull the beans has already initialized the beans, for example, in a Web application where your root context would register `MyConfiguration` and where the servlet context would declare your `screenerJobExecutor` bean that needs to be injected with a bean of type `TaskExecutor`.
You can indeed use
@Qualifier(value = "taskExecutor")
to fix this particular situation as Spring will use the bean name and not the bean type to satisfy the injection target.
Problem
I have the following configuration: ``` @org.springframework.context.annotation.Configuration @EnableJpaRepositories @EnableAsync @EnableScheduling public class MyConfiguration { @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor.setQueueCapacity(50); return executor; } @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(10); return scheduler; } } ``` Then I have a class listening for ContextRefreshEvents, like: ``` @Component public class ScreenerScheduler implements ApplicationListener<ContextRefreshedEvent> { @Inject private TaskScheduler scheduler; @Inject private ApplicationContext context; @Override public void onApplicationEvent(ContextRefreshedEvent event) { } ``` When I run the application (web) I get: ``` Error creating bean with name 'screenerJobExecutor': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.core.task.TaskExecutor example.workflow.ScreenerJobExecutor.executor; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.core.task.TaskExecutor] is defined: expected single matching bean but found 2: taskExecutor,taskScheduler ``` Anyone could help figuring out why spring see two possible types for a TaskScheuler?