5

I have to implement a method with async features in spring boot:

I am a bit confused regarding the location of the annotation asyn, basically my rest controller is as follows:

@RestController
@RequestMapping("/email")
public class EmailController {

    public @ResponseBody ResponseEntity<String> sendMailCon(@RequestBody EmailRequestDto emailRequestDto) {
        LOG.debug("calling method sendMail from controller ");
        //do complex stuff 
        sendMailService.sendEmail(emailRequestDto);
        return new ResponseEntity<>("Mail has been sent successfully", HttpStatus.OK);
    }

And service class is as follows:

@Component
public class SendMailServiceImpl implements SendMailService {

    private static final Logger LOG = LoggerFactory.getLogger(SendMailServiceImpl.class);

    @Autowired
    private JavaMailSender javaMailSender;
@Override
    @Async("threadPoolExecutor")
    public void sendEmail(EmailRequestDto emailRequestDto) {

        LOG.debug("calling method sendMail do complex stuff");
...
}

I have configured my async bean as follows:

@EnableAsync
@Configuration
public class AsyncConfig {

    @Bean(name = "threadPoolExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(25);
        executor.setQueueCapacity(100);
        executor.initialize();
        return executor;
    } 

My question is the annotation @Async on the SendMailServiceImpl is correct or i need to add it on the method sendMailCon from controller?

user1999453
  • 1,297
  • 4
  • 29
  • 65

3 Answers3

4

Basically @Async will make method execute in a separate thread i.e. the caller will not wait for the completion of the called method.Each request to the server is served by a separate thread already , so you have no need to provide @Async on the controller method.

You could keep it in the service layer or better yet another layer down where you actually need the method to be executed asynchronously.In your case you could actually keep the method as async where you use rest template to trigger the mail.If you don't have another class for that it's okay to keep the service layer method as Async.

Read

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39
1

You code is correct and @Async makes your service code to execute in separate thread so controller becomes free immediately after calling the service. It works fine when you don't need to return a response from your execution. But if you need to process the request asynchronously and then collect the response to send back to the caller as REST response then you can use WebAsyncTask with Spring. Please refer below URL which explains the implementation of async REST service. https://www.thetechnojournals.com/2019/10/asynchronous-rest-service.html

Ashok Prajapati
  • 374
  • 2
  • 7
0

Your implementation is correct. In this case you don't need to add @Async on the controller method