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

springboot異步@Async的使用及失效場景介紹

 更新時間:2024年12月24日 10:48:23   作者:YD_1989  
本文主要介紹了springboot異步@Async的使用及失效場景介紹,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

引言

在 java 中很多業(yè)務(wù)涉及到異步線程,比如在業(yè)務(wù)流處理時,需要發(fā)短信發(fā)郵件通知用戶,或者需要上傳一些文件資源到其他服務(wù)器這種耗時的操作。
這種比較耗時的操作如果都在主線程里處理會阻塞整理流程,而且我們也不需要等待處理結(jié)果之后再進行下一步操作,這時候就可以使用異步線程進行處理,這樣主線程不會因為這些耗時的操作而阻塞,保證主線程的流程可以正常進行。

一、@Async 使用位置

  • 在方法上使用該@Async注解,表明該方法是一個異步任務(wù)
  • 在類上面使用該@Async注解,表明該類中的所有方法都是異步任務(wù)

二、@Async 使用

在 Springboot 中使用 @Async:

  • @Async 注解在使用時,如果不指定線程池的名稱,則使用默認的線程池,Spring默認的線程池為 SimpleAsyncTaskExecutor。
  • 方法上一旦標記了這個 @Async 注解,當其它線程調(diào)用這個方法時,就會開啟一個新的子線程去異步處理該業(yè)務(wù)邏輯。
  • 啟動類中增加 @EnableAsync 注解

代碼示例:

本文不做新配置,全部使用默認的線程池及配置。

(1)創(chuàng)建 AsyncService 寫異步方法

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {

    @Async
    public void Async() throws InterruptedException {
        Thread.sleep(10000);
        System.out.println("程序睡眠結(jié)束");

    }

(2)編寫業(yè)務(wù)層 AsyncTestService

package com.ruoyi.system.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncTestService {
    @Autowired
    private AsyncService asyncService;


    public String testSync() throws InterruptedException {
        System.out.println("開始進入方法");
        System.out.println("進行時");
        System.out.println("正在進行時");
		asyncService.Async();
        return "成功";
    }
}

(3)編寫接口 AsyncTestController

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/async/lost")
public class AsyncTestController {

    @Autowired
    private AsyncTestService asyncTestService;

    @RequestMapping(value = "/test", method = {RequestMethod.POST})
    public String testAsync() throws InterruptedException {
        asyncTestService.testSync();
        System.out.println("調(diào)用Controller控制器結(jié)束");
        return "成功";
    }
}

postman 測試:

從下圖測試結(jié)果可知,打印語句 “調(diào)用Controller控制器結(jié)束” 在 “程序睡眠結(jié)束” 之前執(zhí)行,異步實現(xiàn)成功,沒有影響到主線程的任務(wù)。

在這里插入圖片描述

三、注解 @Async 失效的情況

(1)調(diào)用同一個類中的異步方法(內(nèi)部調(diào)用)

從上面的 @Async 使用我們看到,添加注解的異步方法在一個單獨的類 AsyncService 中,然后注入到 AsyncTestService 中進行調(diào)用。如果異步方法和調(diào)用的方法在同一個類中,還會正常進行異步調(diào)用嗎?

AsyncTestService 代碼如下:

@Service
public class AsyncTestService {

    public String testSync() throws InterruptedException {
        System.out.println("開始進入方法");
        System.out.println("進行時");
        System.out.println("正在進行時");
        Async();
        return "成功";
    }

    @Async
    public void Async() throws InterruptedException {
        Thread.sleep(10000);
        System.out.println("程序睡眠結(jié)束");

    }
}

postman 測試:

在這里插入圖片描述

如上圖所示,打印語句 “調(diào)用Controller控制器結(jié)束” 在 “程序睡眠結(jié)束” 之后執(zhí)行,說明異步并沒有生效,程序還是走了主線程。

這是因為 @Async注解是通過aop代理實現(xiàn)的,需要通過JDK動態(tài)代理或者cglib,生成代理對象。異步的功能,是在代理對象中增加的,我們必須調(diào)用代理對象的 testSync() 方法才行。而在類中直接進行方法的內(nèi)部調(diào)用,在 testSync() 方法中調(diào)用Async()方法,調(diào)用的是該類原對象的Async方法,相當于調(diào)用了this.Async()方法,而并非AsyncTestService 代理類的 Async() 方法。 因此,像這種內(nèi)部方法調(diào)用,@Async注解的異步功能會失效。

要想在同一個類中調(diào)用異步方法,需要使用 ApplicationContext 獲得到該類。

AsyncTestService 代碼如下:

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncTestService {

    @Autowired
    private ApplicationContext applicationContext;


    public String testSync() throws InterruptedException {
        AsyncTestService asyncBean = applicationContext.getBean(AsyncTestService.class);
        System.out.println("當前對象是否是代理對象:" + AopUtils.isAopProxy(asyncBean));
        System.out.println("是否是cglib代理對象:" + AopUtils.isCglibProxy(asyncBean));
        System.out.println("是否是jdk代理對象:" + AopUtils.isJdkDynamicProxy(asyncBean));
        System.out.println(asyncBean == this);
        asyncBean.Async();
        return "成功";
    }

    @Async
    public void Async() throws InterruptedException {
        Thread.sleep(10000);
        System.out.println("程序睡眠結(jié)束");

    }
}

postman 測試:

打印控制器語句在前,異步實現(xiàn)成功。

在這里插入圖片描述

(2)未使用 @EnableAsync 注解

在 Springboot 中要開啟@Async注解異步的功能,需要在項目的啟動類,或者配置類上,使用@EnableAsync注解。

@EnableAsync注解相當于一個開關(guān),控制是否開啟@Async注解異步的功能,默認是關(guān)閉的。

@EnableAsync
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

(3)注解@Async的方法不是public方法

異步的方法必須是 public修飾的,否則 aop 代理異常,異步失效。

(4)返回值錯誤

注解 @Async 的返回值只能為 void 或 Future。

(5)方法用static修飾了

使用@Async注解聲明的方法,必須是能被重寫的,很顯然static修飾的方法,是類的靜態(tài)方法,是不允許被重寫的。
因此這種情況下,@Async注解的異步功能會失效。

(6)類中需要使用@Autowired或@Resource等注解自動注入,不能自己手動new對象

(7)方法用final修飾

(8)業(yè)務(wù)類沒加@Service注解

到此這篇關(guān)于springboot異步@Async的使用及失效場景介紹的文章就介紹到這了,更多相關(guān)springboot異步@Async內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

梅河口市| 杭锦旗| 嘉义县| 临江市| 长沙县| 渝中区| 眉山市| 泰和县| 高青县| 天台县| 阳曲县| 定西市| 丰顺县| 平湖市| 扶余县| 三台县| 东阿县| 平顺县| 灵山县| 南京市| 乌兰察布市| 长沙市| 青河县| 隆回县| 建水县| 海兴县| 资溪县| 宁强县| 九台市| 勃利县| 龙海市| 松滋市| 孟津县| 鹤山市| 随州市| 宜丰县| 上蔡县| 枣强县| 武平县| 高邑县| 赫章县|