// Definition du ThreadPoolTaskExecutor
@EnableAsync
public class AsyncConfiguration {
@Bean(name = "someTaskExecutor")
public Executor asyncExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(25);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("some-task-exec-");
executor.initialize();
return executor;
}
}
// Service utilisant le ThreadPoolTaskExecutor
@Service
public class AsyncService {
@Async("someTaskExecutor")
public void doSomethingAsync() {
...
}
Cependant cette pratique a quelques limitations (non exhaustives) :
- Toute méthode @Async invoquée au sein de sa classe ne sera pas asynchrone
- Nécessite de déclarer la méthode annotée @Async, publique
Voici une technique qui permet de tirer parti du ThreadPoolTaskExecutor et de l'asynchrone, sans passer par les annotations @Async. En effet, il peut arriver que l'on souhaite juste lancer un traitement dans un thread, sans formalités
// Definition du ThreadPoolTaskExecutor
@EnableAsync
public class AsyncConfiguration {
@Bean(name = "someTaskExecutor")
public Executor asyncExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(25);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("some-task-exec-");
executor.initialize();
return executor;
}
}
// Service utilisant le ThreadPoolTaskExecutor
@Service
public class AsyncService {
// Import the bean executor defined in AsyncConfiguration
@Autowired
@Qualifier("someTaskExecutor")
private Executor executor;
public void doSomethingWithSomethingAsync() {
// Do something non-async
...
// Then do something async
CompletableFuture.runAsync(() -> {
// Something async
}, this.executor);
}
//@Async("someTaskExecutor")
//public void doSomethingAsync() {
// ...
//}
Voici les étapes : - Définir le ThreadPoolTaskExecutor (ou autre) sous la forme d'un bean
- L'importer dans la classe où l'on souhaite faire un traitement async, via l'annotation @Autowired
- Utiliser CompletableFuture.runAsync/supplyAsync avec en paramètre l'executor, et la fonction à traiter en asynchrone