Spring 始终调用自定义 ThreadPoolTaskExecutor
Spring custom ThreadPoolTaskExecutor is always invoked
我正在尝试将 Spring 上下文复制到 Runnable/Callable 任务以用于特殊情况。我希望其他线程 运行 和之前 运行 一样。
我读过这个How to enable request scope in async task executor
并实现了自定义 ThreadPoolTaskExecutor + 装饰器。
@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(在任何线程中!)。
我该如何解决?
这个post:
描述了问题。 Spring仅当用户未创建自定义执行器时,boot 才会创建默认执行器。
在 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();
}
我正在尝试将 Spring 上下文复制到 Runnable/Callable 任务以用于特殊情况。我希望其他线程 运行 和之前 运行 一样。
我读过这个How to enable request scope in async task executor
并实现了自定义 ThreadPoolTaskExecutor + 装饰器。
@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(在任何线程中!)。 我该如何解决?
这个post:
描述了问题。 Spring仅当用户未创建自定义执行器时,boot 才会创建默认执行器。 在 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();
}