0

I'm trying to copy Spring context to Runnable/Callable tasks for a special case. I want other threads to run as they run before.

I've read this How to enable request scope in async task executor

and implemented a custom ThreadPoolTaskExecutor + decorator.

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

I was planning to use this executor as follows:

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

However, contextExecutor is always invoked (in any thread!). How can I fix it?

1 Answer 1

1

This post:

How to create additional TaskExecutor beside TaskExecutionAutoConfiguration?

describes the issue. Springboot creates a default Executor only if user did not create a custom one. In SpringBoot 2+ you have to use

@AutoConfigureAfter(TaskExecutionAutoConfiguration.class) 

on your custom configuration.

In previous Spring versions however, no TaskExecutionAutoConfiguration exists and Executor is created by a factory. Using lines below, you can create the exect copy of default executor, created by 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(); } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.