天天看點

Spring源碼學習之:@async 方法上添加該注解實作異步調用的原理

在我們使用spring架構的過程中,在很多時候我們會使用@async注解來異步執行某一些方法,提高系統的執行效率。今天我們來探讨下 spring 是如何完成這個功能的。

spring

在掃描bean的時候會掃描方法上是否包含@async的注解,如果包含的,spring會為這個bean動态的生成一個子類,我們稱之為代理類(?),

代理類是繼承我們所寫的bean的,然後把代理類注入進來,那此時,在執行此方法的時候,會到代理類中,代理類判斷了此方法需要異步執行,就不會調用父類

(我們原本寫的bean)的對應方法。spring自己維護了一個隊列,他會把需要執行的方法,放入隊列中,等待線程池去讀取這個隊列,完成方法的執行,

進而完成了異步的功能。我們可以關注到再配置task的時候,是有參數讓我們配置線程池的數量的。因為這種實作方法,是以在同一個類中的方法調用,添加@async注解是失效的!,原因是當你在同一個類中的時候,方法調用是在類體内執行的,spring無法截獲這個方法調用。

那在深入一步,spring為我們提供了AOP,面向切面的功能。他的原理和異步注解的原理是類似的,spring在啟動容器的時候,會掃描切面所定義的

類。在這些類被注入的時候,所注入的也是代理類,當你調用這些方法的時候,本質上是調用的代理類。通過代理類再去執行父類相對應的方法,那spring隻

需要在調用之前和之後執行某段代碼就完成了AOP的實作了!

   那最後我們還有一個問題,spring是如何動态的生成某一個類的子類的?代理類?

閱讀目錄

<a href="http://www.cnblogs.com/zhengbin/p/6104502.html#_label0">簡單介紹:</a>

<a href="http://www.cnblogs.com/zhengbin/p/6104502.html#_label1">開啟@Async注解:</a>

<a href="http://www.cnblogs.com/zhengbin/p/6104502.html#_label2">栗子:</a>

<a href="http://www.cnblogs.com/zhengbin/p/6104502.html#_label3">官方文檔:</a>

<a></a>

Spring為任務排程與異步方法執行提供了注解支援。通過在方法上設定@Async注解,可使得方法被異步調用。也就是說調用者會在調用時立即傳回,而被調用方法的實際執行是交給Spring的TaskExecutor來完成。

<a>+ View code</a>

同時加入&lt;context:component-scan /&gt;掃描注解。

輸出結果:

同步調用會按代碼順序依次進行下去,如果哪裡需要等待,那麼就阻塞在那裡,不再向下繼續進行。

異步調用,通過開啟新的線程來執行調用的方法,不影響主線程。異步方法實際的執行交給了Spring的TaskExecutor來完成。

通過直接擷取傳回值得方式是不行的,這裡就需要用到異步回調,異步方法傳回值必須為Future&lt;&gt;,就像Callable與Future。