Dhruv Singh Chandel
Dhruv Singh Chandel

Reputation: 81

@Async not working for method having return type void

I wanted to make a method writing to DB as async using @Async annotation.

I marked the class with the annotation @EnableAsync:

@EnableAsync
public class FacialRecognitionAsyncImpl {

    @Async
    public void populateDataInPushQueue(int mediaId, int studentId) {
        //myCode
    }
}

while calling the populateDataInPushQueue method, the write operation should be executed in another thread and the flow should continue from the class I am calling this method. But this is not happening and the program execution is waiting for this method to complete.

Upvotes: 8

Views: 4272

Answers (2)

Alexander Petrov
Alexander Petrov

Reputation: 9492

In my opinion, you are missing @Configuration annotation and your async service is not component scanned. Here is an example code fragment that should do the trick:

@Configuration
@EnableAsync  //should be placed together.
public class FacialRecognitionAsyncService {

     @Async
     public void populateDataInPushQueue(int mediaId, int studentId) {
         //myCode
     }
} 

@Configuration
@EnableAsync
public class FacialServiceConfig {

    // this will make your service to be scanned.
    @Bean
    public FacialRecognitionAsyncService createFacialRecognitionService() {
        return new FacialRecognitionAsyncService();
    }

}

Now the service bean that is invoking the async method. Notice that it has been dependency injected. This way spring AOP proxies will be invoked on each invocation fo the facialService. Spring uses AOP in the back scenes in order to implement @Async.

@Service
public class MyBusinessService {

@Autowire
FacialRecognitionAsyncService  facialService;

public myBusinessMethod() {
   facialService.populateDataInPushQueue()
}

Notice that FacialService is injected in MyService through dependency injection.

Upvotes: 4

Nikolas
Nikolas

Reputation: 44398

The @Async annotation has few limitations - check whether those are respected:

  • it must be applied to public methods only
  • it cannot be called from the same class as defined
  • the return type must be either void or Future

The following can be found at the documentation of @EnableAsync:

Please note that proxy mode allows for the interception of calls through the proxy only; local calls within the same class cannot get intercepted that way.

Another fact is that the class annotated with @EnableAsync must be a @Configuration as well. Therefore start with an empty class:

@EnableAsync
@Configuration
public class AsyncConfiguration { }

Upvotes: 13

Related Questions