最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring @async方法如何添加注解實(shí)現(xiàn)異步調(diào)用

 更新時(shí)間:2020年01月15日 14:56:05   作者:沫小淘  
這篇文章主要介紹了Spring @async方法如何添加注解實(shí)現(xiàn)異步調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了Spring @async方法如何添加注解實(shí)現(xiàn)異步調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

在我們使用spring框架的過(guò)程中,在很多時(shí)候我們會(huì)使用@async注解來(lái)異步執(zhí)行某一些方法,提高系統(tǒng)的執(zhí)行效率。今天我們來(lái)探討下 spring 是如何完成這個(gè)功能的。

spring 在掃描bean的時(shí)候會(huì)掃描方法上是否包含@async的注解,如果包含的,spring會(huì)為這個(gè)bean動(dòng)態(tài)的生成一個(gè)子類(lèi),我們稱(chēng)之為代理類(lèi)(?), 代理類(lèi)是繼承我們所寫(xiě)的bean的,然后把代理類(lèi)注入進(jìn)來(lái),那此時(shí),在執(zhí)行此方法的時(shí)候,會(huì)到代理類(lèi)中,代理類(lèi)判斷了此方法需要異步執(zhí)行,就不會(huì)調(diào)用父類(lèi) (我們?cè)緦?xiě)的bean)的對(duì)應(yīng)方法。spring自己維護(hù)了一個(gè)隊(duì)列,他會(huì)把需要執(zhí)行的方法,放入隊(duì)列中,等待線程池去讀取這個(gè)隊(duì)列,完成方法的執(zhí)行, 從而完成了異步的功能。

我們可以關(guān)注到再配置task的時(shí)候,是有參數(shù)讓我們配置線程池的數(shù)量的。因?yàn)檫@種實(shí)現(xiàn)方法,所以在同一個(gè)類(lèi)中的方法調(diào)用,添加@async注解是失效的!,原因是當(dāng)你在同一個(gè)類(lèi)中的時(shí)候,方法調(diào)用是在類(lèi)體內(nèi)執(zhí)行的,spring無(wú)法截獲這個(gè)方法調(diào)用。

那在深入一步,spring為我們提供了AOP,面向切面的功能。他的原理和異步注解的原理是類(lèi)似的,spring在啟動(dòng)容器的時(shí)候,會(huì)掃描切面所定義的 類(lèi)。在這些類(lèi)被注入的時(shí)候,所注入的也是代理類(lèi),當(dāng)你調(diào)用這些方法的時(shí)候,本質(zhì)上是調(diào)用的代理類(lèi)。通過(guò)代理類(lèi)再去執(zhí)行父類(lèi)相對(duì)應(yīng)的方法,那spring只 需要在調(diào)用之前和之后執(zhí)行某段代碼就完成了AOP的實(shí)現(xiàn)了!

那最后我們還有一個(gè)問(wèn)題,spring是如何動(dòng)態(tài)的生成某一個(gè)類(lèi)的子類(lèi)的?代理類(lèi)?

簡(jiǎn)單介紹:

Spring為任務(wù)調(diào)度與異步方法執(zhí)行提供了注解支持。通過(guò)在方法上設(shè)置@Async注解,可使得方法被異步調(diào)用。也就是說(shuō)調(diào)用者會(huì)在調(diào)用時(shí)立即返回,而被調(diào)用方法的實(shí)際執(zhí)行是交給Spring的TaskExecutor來(lái)完成。

開(kāi)啟@Async注解:

<task:annotation-driven executor="annotationExecutor" />
<!-- 支持 @Async 注解 -->
<task:executor id="annotationExecutor" pool-size="20"/>

同時(shí)加入<context:component-scan />掃描注解。

為了比較,先來(lái)一個(gè)同步調(diào)用:

@Component
public class TestAsyncBean {
  public void sayHello4() throws InterruptedException {
    Thread.sleep(2 * 1000);//網(wǎng)絡(luò)連接中 。。。消息發(fā)送中。。。
    System.out.println("我愛(ài)你啊!");
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/applicationContext.xml"})
public class TestAsync {
  @Test
  public void test_sayHello4() throws InterruptedException, ExecutionException {
    System.out.println("你不愛(ài)我了么?");
    testAsyncBean.sayHello4();
    System.out.println("回的這么慢, 你肯定不愛(ài)我了, 我們還是分手吧。。。");
    Thread.sleep(3 * 1000);// 不讓主進(jìn)程過(guò)早結(jié)束
  }
}

輸出結(jié)果:

你不愛(ài)我了么?
我愛(ài)你啊!
回的這么慢, 你肯定不愛(ài)我了, 我們還是分手吧。。。 

 同步調(diào)用會(huì)按代碼順序依次進(jìn)行下去,如果哪里需要等待,那么就阻塞在那里,不再向下繼續(xù)進(jìn)行。

使用@Async的異步調(diào)用:

@Component
public class TestAsyncBean {
  @Async
  public void sayHello3() throws InterruptedException {
    Thread.sleep(2 * 1000);//網(wǎng)絡(luò)連接中 。。。消息發(fā)送中。。。
    System.out.println("我愛(ài)你啊!");
  }
}
@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("你不愛(ài)我了么?");
    testAsyncBean.sayHello3();
    System.out.println("你竟無(wú)話可說(shuō), 我們分手吧。。。");
    Thread.sleep(3 * 1000);// 不讓主進(jìn)程過(guò)早結(jié)束
  }
}

輸出結(jié)果:

你不愛(ài)我了么?
你竟無(wú)話可說(shuō), 我們分手吧。。。
我愛(ài)你啊!

異步調(diào)用,通過(guò)開(kāi)啟新的線程來(lái)執(zhí)行調(diào)用的方法,不影響主線程。異步方法實(shí)際的執(zhí)行交給了Spring的TaskExecutor來(lái)完成。

上面這種方式是沒(méi)有返回值的,下面嘗試有返回值的異步調(diào)用:

@Component
public class TestAsyncBean {
  @Async
  public String sayHello2() throws InterruptedException {
    Thread.sleep(2 * 1000);//網(wǎng)絡(luò)連接中 。。。消息發(fā)送中。。。
    return "我愛(ài)你啊!";// 調(diào)用方調(diào)用后會(huì)立即返回,所以返回null
  }
}
@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("你不愛(ài)我了么?");
    System.out.println(testAsyncBean.sayHello2());
    System.out.println("你說(shuō)的啥? 我們還是分手吧。。。");
    Thread.sleep(3 * 1000);// 不讓主進(jìn)程過(guò)早結(jié)束
  }
}

輸出結(jié)果:

你不愛(ài)我了么?
null
你說(shuō)的啥? 我們還是分手吧。。。

通過(guò)直接獲取返回值得方式是不行的,這里就需要用到異步回調(diào),異步方法返回值必須為Future<>,就像Callable與Future。

下面通過(guò)AsyncResult<>來(lái)獲得異步調(diào)用的返回值:

@Component
public class TestAsyncBean {
  @Async
  public Future<String> sayHello1() throws InterruptedException {
    int thinking = 2;
    Thread.sleep(thinking * 1000);//網(wǎng)絡(luò)連接中 。。。消息發(fā)送中。。。
    System.out.println("我愛(ài)你啊!");
    return new AsyncResult<String>("發(fā)送消息用了"+thinking+"秒");
  }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/applicationContext.xml"})
public class TestAsync {
  @Autowired
  private TestAsyncBean testAsyncBean;
  @Test
  public void test_sayHello1() throws InterruptedException, ExecutionException {
    Future<String> future = null;
    System.out.println("你不愛(ài)我了么?");
    future = testAsyncBean.sayHello1();
    System.out.println("你竟無(wú)話可說(shuō), 我們分手吧。。。");
    Thread.sleep(3 * 1000);// 不讓主進(jìn)程過(guò)早結(jié)束
    System.out.println(future.get());
  }
}

輸出結(jié)果:

你不愛(ài)我了么?
你竟無(wú)話可說(shuō), 我們分手吧。。。
我愛(ài)你啊!

發(fā)送消息用了2秒

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot  jdbctemplate使用方法解析

    SpringBoot jdbctemplate使用方法解析

    這篇文章主要介紹了SpringBoot jdbctemplate使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • mybatis原理概述入門(mén)教程

    mybatis原理概述入門(mén)教程

    這篇文章主要介紹了在今天這篇博文中,我將要介紹一下mybatis的框架原理,以及mybatis的入門(mén)程序,實(shí)現(xiàn)用戶的增刪改查,她有什么優(yōu)缺點(diǎn)以及mybatis和hibernate之間存在著怎么樣的關(guān)系,大家這些問(wèn)題一起通過(guò)本文學(xué)習(xí)吧
    2016-09-09
  • Java實(shí)現(xiàn)分頁(yè)的幾種方法詳細(xì)解析

    Java實(shí)現(xiàn)分頁(yè)的幾種方法詳細(xì)解析

    這篇文章主要介紹了Java實(shí)現(xiàn)分頁(yè)的幾種方法詳細(xì)解析,在Java中想實(shí)現(xiàn)分頁(yè)功能有幾種常用的方法,今天我們就來(lái)詳細(xì)解析一下,文中提供了解決思路和部分實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-11-11
  • java Apache poi 對(duì)word doc文件進(jìn)行讀寫(xiě)操作

    java Apache poi 對(duì)word doc文件進(jìn)行讀寫(xiě)操作

    這篇文章主要介紹了Apache poi 對(duì)word doc文件進(jìn)行讀寫(xiě)操作的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java Servlet上傳圖片到指定文件夾并顯示圖片

    Java Servlet上傳圖片到指定文件夾并顯示圖片

    在學(xué)習(xí)Servlet過(guò)程中,針對(duì)圖片上傳做了一個(gè)Demo,如果大家對(duì)Java Servlet上傳圖片到指定文件夾并顯示圖片功能感興趣的朋友大家通過(guò)本文一起學(xué)習(xí)吧
    2017-08-08
  • java自動(dòng)生成接口文檔完整代碼示例

    java自動(dòng)生成接口文檔完整代碼示例

    在軟件開(kāi)發(fā)中,編寫(xiě)接口文檔是一項(xiàng)必要但繁瑣的任務(wù),為了簡(jiǎn)化這一過(guò)程,可以通過(guò)使用Swagger2和Swagger-UI來(lái)自動(dòng)生成接口文檔,這篇文章主要介紹了java自動(dòng)生成接口文檔的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • java線程并發(fā)semaphore類(lèi)示例

    java線程并發(fā)semaphore類(lèi)示例

    Java 5.0里新加了4個(gè)協(xié)調(diào)線程間進(jìn)程的同步裝置,它們分別是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介紹Semaphore,Semaphore是用來(lái)管理一個(gè)資源池的工具,可以看成是個(gè)通行證
    2014-01-01
  • Spring Boot 中application.yml與bootstrap.yml的區(qū)別

    Spring Boot 中application.yml與bootstrap.yml的區(qū)別

    其實(shí)yml和properties文件是一樣的原理,且一個(gè)項(xiàng)目上要么yml或者properties,二選一的存在。這篇文章給大家介紹了Spring Boot 中application.yml與bootstrap.yml的區(qū)別,感興趣的朋友一起看看吧
    2018-04-04
  • Java?工具類(lèi)實(shí)現(xiàn)音頻音量提升

    Java?工具類(lèi)實(shí)現(xiàn)音頻音量提升

    本文主要介紹了可以將音頻提升音量的一個(gè)java工具類(lèi)示例代碼,代碼具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴來(lái)了解一下吧,,希望能夠給你帶來(lái)幫助
    2021-11-11
  • java并發(fā)之AtomicInteger源碼分析

    java并發(fā)之AtomicInteger源碼分析

    AtomicInteger是java并發(fā)包下面提供的原子類(lèi),主要操作的是int類(lèi)型的整型,通過(guò)調(diào)用底層Unsafe的CAS等方法實(shí)現(xiàn)原子操作。下面小編和大家一起學(xué)習(xí)一下
    2019-05-05

最新評(píng)論

格尔木市| 天峨县| 谢通门县| 青浦区| 塔城市| 沭阳县| 晋江市| 崇文区| 千阳县| 巴彦淖尔市| 布尔津县| 明水县| 博客| 汽车| 云霄县| 南丹县| 高唐县| 昭平县| 金乡县| 天等县| 凤山县| 祁东县| 临邑县| 类乌齐县| 达日县| 浦城县| 南昌市| 吉隆县| 扎赉特旗| 安庆市| 云安县| 天气| 英山县| 雅江县| 黎川县| 星子县| 章丘市| 柘城县| 扶风县| 大理市| 永仁县|