Spring将TaskExecutor和TaskScheduler用作相同类型

Joa*_*ira 2 java spring

我有以下配置:

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

}
Run Code Online (Sandbox Code Playgroud)

然后,我有一个侦听ContextRefreshEvents的类,例如:

@Component
public class ScreenerScheduler implements ApplicationListener<ContextRefreshedEvent> {

    @Inject
    private TaskScheduler scheduler;

    @Inject
    private ApplicationContext context;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
}
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序(网络)时,我得到:

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
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助弄清楚为什么spring可以看到TaskScheuler的两种可能的类型?

Sot*_*lis 6

这个@Bean方法

@Bean
public TaskScheduler taskScheduler() {
Run Code Online (Sandbox Code Playgroud)

返回类型ThreadPoolTaskScheduler

public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
    implements TaskScheduler, SchedulingTaskExecutor {
Run Code Online (Sandbox Code Playgroud)

所以它适合两个接口,TaskSchedulerTaskExecutor(超类型SchedulingTaskExecutor)。

如果您尝试注入一个TaskExecutor类似堆栈跟踪这样的类型的字段

Could not autowire field: private org.springframework.core.task.TaskExecutor...
Run Code Online (Sandbox Code Playgroud)

Spring无法选择哪一个。

ApplicationContext当您尝试从中拉出Bean的Bean已经初始化了Bean时,例如在Web应用程序中,您的根上下文将MyConfiguration在其中注册,而Servlet上下文将声明您的screenerJobExecutorBean需要注入一个A。类型的bean TaskExecutor

您确实可以使用

@Qualifier(value = "taskExecutor")
Run Code Online (Sandbox Code Playgroud)

为了解决这种特殊情况,Spring将使用bean名称而不是bean类型来满足注入目标。