You probably know Spring and probably know what the awesome principal in Spring IoC and AOP. More than that, Spring also offer a lot of great features which can help developer quickly to develop their application. One of them is Asynchronous (@Async) to allow your method to run it as another thread and not block the main thread. From my observation it’s similar way you implement a new thread in core java but Spring give you a quick way to day. Now we will break down the situation and see why it’s good for you.
Imagine you have to develop an endpoint to allow create new product, since product created you also need to send emails for all people who were subscribed to let them know new product launched. Usually you will write:
Endpoint ( I called in TestController.java ):
@RestController @RequestMapping("/test-api") public class TestController { @Inject private ProductService productService; @PostMapping(value = "/create-product", consumes = {MediaType.APPLICATION_JSON_VALUE}) public HttpEntity<?> createProduct(@RequestBody ProductDTO productDTO) { productService.saveProduct(productDTO); productService.sendDistributionList(); return new ResponseEntity<>(HttpStatus.OK); } }
@Service public class ProductService { public void saveProduct(ProductDTO dto) { System.out.println("Saved product"); sendDistributionList(); } public void sendDistributionList() { // assume we have 50K email need to be subscribed when new product added for (int i=0; i<50000; i++) { System.out.println("Sending email"); } }
Ok, now we will try to call that endpoint, you can use any rest client tool , I used Postman here. (If you notice in service class, I demonstrate we need to send 50K emails to subscriber which would take a time to accomplished). The time execution is ~350-400ms. Wow sending a long distribution really take time, and in this case if user using your application, call this endpoint they have to wait ~350-400ms before got 200 OK response code and it means your UI would be blocked ( un-responsive ) till getting 200 OK code returned. Hmm.. that is not really good to block UI for user and let them wait a long time. So thinking more....We realize that sending email might be transparent with user and they might not care if emails sent successfully or not. They might need to care if emails kicked to send or not. What the user expect is they need to know if they created product successfully or not, it seems more important rather than sending emails. Therefore we can think different approach to allow sending emails still happened but... in different _thread_. When your code is working under another thread of process application, it won’t block main thread and can run as async, it means you can know result later and you don’t need to wait. Sometime we call that is non-blocking.Ok, so let’s modify a bit in code at ProductService.java to allow sending Distribution works as another thread. For Spring, you just simply put @Async annotation before method, let see below
@Async public void sendDistributionList() { // assume we have 50K email need to be subscribed when new product added for (int i=0; i<50000; i++) { System.out.println("Sending email"); } }
Great, seems it's done. Let try to hit endpoint again and see. You won't have to wait sending emails completed more, since saveProduct() completed, the UI will be repsonsive immediately, if you notice the execution in postman, the time you got 200OK code would be around ~20ms. This change still ensure emals sending kicked off, just you don't need to wait sending completed.
This is one of good example to see how async in spring is. Depend on your imagining, this can be used in another situation when you want do something in asynchronous.