Spring Boot: one common way to run async logic is @Async. Also the main Application class should be annotated with @EnableAsync. Spring Boot: one common way to run async logic is @Async.
But there is an important detail:
Calling an @Async method from the SAME class will NOT start a new thread because Spring proxy interception is bypassed.
Works if call async method from another service
Same class:
- enable proxy exposure
- call through
self
Minimal examples:
@SpringBootApplication@EnableAsync@EnableAspectJAutoProxy(exposeProxy = true)public class App {}
Separate service (Simpler and easier to read:
@Servicepublic class S3Service { @Async public Future<String> sendFile() { return new AsyncResult<>(Thread.currentThread().getName()); }}}
@Service@EnableAspectJAutoProxy(exposeProxy = true)public class ReportService { public Future<String> generate() { ReportService self = (ReportService) AopContext.currentProxy(); return self.generateAsync(); } @Async public Future<String> generateAsync() { return new AsyncResult<>(Thread.currentThread().getName()); }}
Same class approach:
@Servicepublic class ReportService { public Completable<String> generate() { ReportService self = (ReportService) AopContext.currentProxy(); return self.generateAsync(); } @Async public Complet<String> generateAsync() { return CompletableFuture.completedFuture( Thread.currentThread().getName()); }}
Minimal test with Awaitility:
@SpringBootTestclass AsyncTest { @Autowired private S3Service s3Service; @Test void shouldRunAsync() throws Exception { Future<String> future = s3Service.sendFile(); // BLOCKING WAIT String threadName = future.get(); assertThat(threadName) .isNotEqualTo(Thread.currentThread().getName()); }}

Hinterlasse einen Kommentar