Spring 對異步任務具有很好的支持。這篇文章,我們透過 Spring Boot 來講解下單發服務模式和請求應答模式。
Spring Boot 集成異步任務
在 Spring Boot 中使用 @EnableAsync 開啟異步支持。
- @Configuration
- @EnableAsync
- public class AsyncConfig {
- }
現在,我們在 Spring Boot 中,我們只需要通過使用 @Async 注解就能將原來的同步方法變為異步方法。
單發服務模式
多個服務之間邏輯上不存在相互依賴關系,執行先后順序沒有嚴格的要求,邏輯上可以被並行執行。對於單發服務只有請求,沒有應答,很容易設計成異步的。發起服務調用后。立即返回,不需要同步阻塞等待應答。
- @Service
- public class MsgServer {
- @Async
- public void sendA() throws Exception {
- System.out.println("send A");
- Long startTime = System.currentTimeMillis();
- Thread.sleep(2000);
- Long endTime = System.currentTimeMillis();
- System.out.println("耗時:" + (endTime - startTime));
- }
- @Async
- public void sendB() throws Exception {
- System.out.println("send B");
- Long startTime = System.currentTimeMillis();
- Thread.sleep(2000);
- Long endTime = System.currentTimeMillis();
- System.out.println("耗時:" + (endTime - startTime));
- }
- }
此時,因為我們添加了 @Async 注解,它就變成了異步方法。
- @RunWith(SpringJUnit4ClassRunner.class)
- @SpringApplicationConfiguration(classes = WebMain.class)
- public class AsyncTest {
- @Autowired
- private MsgServer msgServer;
- @Test
- public void test() throws Exception {
- msgServer.sendA();
- msgServer.sendB();
- }
- }
請求應答模式
對於,請求的內容,需要應答,例如我們需要在多個方法調用都完成后,才進行接下來的操作,此時我們可以利用 Java 的 Future-Listener 機制來實現異步服務調用。
- @Service
- public class MsgFutureServer {
- public static Random random = new Random();
- @Async
- public Future<String> sendA() throws Exception {
- System.out.println("send A");
- Long startTime = System.currentTimeMillis();
- Thread.sleep(2000);
- Long endTime = System.currentTimeMillis();
- System.out.println("耗時:" + (endTime - startTime));
- return new AsyncResult<String>("success");
- }
- @Async
- public Future<String> sendB() throws Exception {
- System.out.println("send B");
- Long startTime = System.currentTimeMillis();
- Thread.sleep(2000);
- Long endTime = System.currentTimeMillis();
- System.out.println("耗時:" + (endTime - startTime));
- return new AsyncResult<String>("success");
- }
- }
下面的單元測試,在等待完成兩個異步任務后,再統計具體耗時時長。
- @RunWith(SpringJUnit4ClassRunner.class)
- @SpringApplicationConfiguration(classes = WebMain.class)
- public class AsyncFutureTest {
- @Autowired
- private MsgFutureServer msgFutureServer;
- @Test
- public void test() throws Exception {
- long startTime = System.currentTimeMillis();
- Future<String> task1 = msgFutureServer.sendA();
- Future<String> task2 = msgFutureServer.sendB();
- while(true) {
- if(task1.isDone() && task2.isDone() ) {
- break;
- }
- }
- long endTime = System.currentTimeMillis();
- System.out.println("總耗時:" + (endTime - startTime));
- }
- }
源代碼
相關示例完整代碼: springboot-action
(完)
