The main goal of this project is to explore basic features of @Async
spring annotation and compare results with non-concurrent approach.
- references
This project shows how to create asynchronous queries using Spring.
Our approach is to run expensive jobs in the background and wait
for the results using Java’s CompletableFuture interface.
- spring boot concurrency options
- java executors and futures
- completable futures
- @Async annotation
- reactive programming
- virtual threads
- structured concurrency
-
Enable asynchronous support:
@Configuration @EnableAsync class AsyncConfig { @Bean Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(4); executor.setMaxPoolSize(4); executor.setQueueCapacity(500); executor.setThreadNamePrefix("EmailSender-"); executor.initialize(); return executor; } }Remark:
asyncExecutor()is used to customize default behaviour and is not mandatory. -
Annotate method with
@Async, and set return type toCompletableFuture<XXX>whereXXXis a wanted return type, for example:String customMethod() { ... }should be transformed to:
CompletableFuture<String> customMethod() { ... } -
Consume it with
Completable API, for example:CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[]{})).join();CompletableFuture.allOf(completableFuture1, completableFuture2).join();
-
Extract requested return (note that
get()throws checked exception):XXX xxx = completableFuture.join()
email-service- microservice responsible for sending emails to given usersEmailController- REST controller; receiveslogin-messagemap, then asksslow-user-serviceforemailsand sends messages- in
EmailServicewe have the same methods:@Asyncmethod -asyncSend- concurrently sends messages- non-concurrent method -
send
- in
AppRunnerwe simulate interactions and compare times
slow-user-serviceUserControllerreturnsUserbean (login, name, email...) for given login- in
UserRepositorywe sleep thread foruser.repository.delay.seconds(configurable inapplication.properties) and then return requested user
Coverage: 93%