Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async not working on controller's abstract super class method

I have a BaseRestController class that Rest controllers extend. It has a method that I want to run asynchronously.

public abstract class BaseRestController {
    ...

    @Async("someThreadPoolTaskExecutor")
    public void someAsyncTask() {
        ...
    }

}
@RestController
public class MyRestController extends BaseRestController {
    ...

    @GetMapping("/some/path")
    public SomeEntity getSomething() {
        ...
        this.someAsyncTask();
    }        
}

I have enabled Async using annotation, implemented a method that gets someThreadPoolTaskExecutor TaskExecutor and all. If I put @Async("someThreadPoolTaskExecutor") on a Service's (class annotated with @Service) method, it works but if I do so with someAsyncTask() in BaseRestController the code won't run asynchronously. Decorating the class with @Component didn't work either.

Spring guide on Async didn't help either. In it's demo, it also demonstrates Async with service class.

While, in the process, I realized that the behavior I wanted to implement was better off delegated to a service class, I am curious as to understand why the above won't work.

I'm using 2.1.0.RELEASE of Spring Boot.

like image 206
Dilip Raj Baral Avatar asked May 31 '26 20:05

Dilip Raj Baral


1 Answers

There are couple of rules for @Async, you are doing the self-invocation which won't work here

  • it must be applied to public methods only
  • self-invocation – calling the async method from within the same class – won’t work

The reasons are simple – the method needs to be public so that it can be proxied. And self-invocation doesn’t work because it bypasses the proxy and calls the underlying method directly.

like image 77
Deadpool Avatar answered Jun 03 '26 08:06

Deadpool