【问题标题】:Spring custom ThreadPoolTaskExecutor is always invoked总是调用 Spring 自定义的 ThreadPoolTask​​Executor
【发布时间】:2019-02-26 12:16:47
【问题描述】:

我正在尝试将 Spring 上下文复制到 Runnable/Callable 任务以用于特殊情况。我希望其他线程像以前一样运行。

我读过这个How to enable request scope in async task executor

并实现了一个自定义的 ThreadPoolTask​​Executor + 装饰器。

@Configuration
public class ContextCopyConfig {

    private Integer connectionsLimit=10;

    @Bean(name = "contextExecutor")
    public Executor contextExecutor() {
        ThreadPoolTaskExecutor poolExecutor = new ThreadPoolTaskExecutor();
        poolExecutor.setTaskDecorator(new ContextCopyingDecorator());
        poolExecutor.setMaxPoolSize(connectionsLimit);
        poolExecutor.setCorePoolSize(connectionsLimit);

        poolExecutor.initialize();
        return poolExecutor;
    }

}

我打算按如下方式使用这个执行器:

@Autowired
@Qualifier(value = "contextExecutor")
private Executor contextExecutor;

public void parallelHere() throws IOException, InterruptedException, ExecutionException {
    Collection<Callable<Pair<String, OutputStream>>> tasks = new ArrayList<>(); //some tasks

    //ExecutorService executor = Executors.newFixedThreadPool(connectionsLimit); 

    List<Future<Pair<String, OutputStream>>> results = ((ThreadPoolTaskExecutor) contextExecutor).getThreadPoolExecutor().invokeAll(tasks);
    ((ThreadPoolTaskExecutor) contextExecutor).getThreadPoolExecutor().shutdown(); //always reclaim resources
}

然而,contextExecutor 总是被调用(在任何线程中!)。 我该如何解决?

【问题讨论】:

    标签: java spring spring-boot java.util.concurrent


    【解决方案1】:

    这篇文章:

    How to create additional TaskExecutor beside TaskExecutionAutoConfiguration?

    描述问题。只有当用户没有创建自定义执行器时,Springboot 才会创建一个默认执行器。 在 SpringBoot 2+ 中,您必须使用

    @AutoConfigureAfter(TaskExecutionAutoConfiguration.class)
    

    关于您的自定义配置。

    然而,在以前的 Spring 版本中,不存在 TaskExecutionAutoConfiguration 并且 Executor 是由工厂创建的。使用下面的行,您可以创建由 Spring 创建的默认执行程序的副本。

    @Primary
    @Bean
    //see package org.springframework.aop.interceptor.AsyncExecutionInterceptor
    public Executor getDefaultExecutor(){
        //     Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
        //     return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
        return new SimpleAsyncTaskExecutor();
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 1970-01-01
      • 2018-07-29
      • 2017-03-02
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 2018-02-20
      • 2019-11-18
      相关资源
      最近更新 更多