一、介紹
spring爲任務調度與異步方法的執行提供了註解支持。
通過在方法上設置@Async註解,可以實現方法的異步調用。簡單說,就是調用者在調用後會立刻得到返回,但實際的方法並未完全執行,而是交給了spring的TaskExecutor來執行。
二、開啓對@Async註解支持
<!-- 啓動對@Async註解,異步方法執行的支持 -->
<task:annotation-driven executor="asyncExecutor" />
<task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10"/>
三、舉個栗子
首先,同步調用的栗子:
@Component
public class TestAsyncBean {
@Async
public String sayHello2() throws InterruptedException {
Thread.sleep(2 * 1000);//模擬網絡請求,發送消息等消耗的時間
System.out.println("你好,小黑");
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/applicationContext.xml"})
public class TestAsync {
@Autowired
private TestAsyncBean testAsyncBean;
@Test
public void test_sayHello2() throws InterruptedException, ExecutionException {
System.out.println("小白,你好");
System.out.println(testAsyncBean.sayHello2());
System.out.println("你叫我啥?");
Thread.sleep(3 * 1000);// 不讓主進程過早結束,保證異步方法的正確執行
}
}
同步調用結果:
小白,你好
小黑,你好
你叫我啥?
使用@Async的異步調用:
@Component
public class TestAsyncBean {
@Async
public void sayHello3() throws InterruptedException {
Thread.sleep(2 * 1000);//網絡連接中 。。。消息發送中。。。
System.out.println("小黑,你好");
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/applicationContext.xml"})
public class TestAsync {
@Autowired
private TestAsyncBean testAsyncBean;
@Test
public void test_sayHello3() throws InterruptedException, ExecutionException {
System.out.println("小白,你好");
testAsyncBean.sayHello3();
System.out.println("你叫我啥?");
Thread.sleep(3 * 1000);// 不讓主進程過早結束
}
}
異步調用結果:
小白,你好
你叫我啥?
小黑,你好
四、結論
通過上面的栗子,可以看出,異步調用,是把異步方法執行的任務,交給spring的TaskExecutor來執行,調用者會立即得到調用返回,而不需要等到調用方法完全執行完,才獲得放回值。
舉個實際應用中的栗子,
比如在項目中做一個開放接口,這個開放接口是讓其他人員來請求調用的,而該接口內部邏輯複雜,程序執行時間長,而調用者並不關心最終執行結果,只需要知道是否確切的調用成功了,那麼就可以使用異步調用來避免接口長時間的請求等待了,也避免了請求斷開造成的一系列風險操作。