日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

@Async注解失效的九種場景

來源: 責編: 時間:2024-05-08 09:23:37 165觀看
導讀前言最近有粉絲問了我一個問題:他在項目某個方法使用@Async注解,但是該方法還是同步執行了,異步不起作用,到底是什么原因呢?偽代碼如下:@Slf4j@Servicepublic class UserService { @Async public void async(String v

前言

最近有粉絲問了我一個問題:他在項目某個方法使用@Async注解,但是該方法還是同步執行了,異步不起作用,到底是什么原因呢?8xK28資訊網——每日最新資訊28at.com

偽代碼如下:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:" + value);    }}

這個問題還是比較有意思的,今天這篇文章總結了@Async注解失效的9種場景,希望對你會有所幫助。8xK28資訊網——每日最新資訊28at.com

圖片圖片8xK28資訊網——每日最新資訊28at.com

1 未使用@EnableAsync注解

在Spring中要開啟@Async注解異步的功能,需要在項目的啟動類,或者配置類上,使用@EnableAsync注解。8xK28資訊網——每日最新資訊28at.com

例如:8xK28資訊網——每日最新資訊28at.com

@EnableAsync@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

@EnableAsync注解相當于一個開關,控制是否開啟@Async注解異步的功能,默認是關閉的。8xK28資訊網——每日最新資訊28at.com

如果在項目的啟動類上沒使用@EnableAsync注解,則@Async注解異步的功能不生效。8xK28資訊網——每日最新資訊28at.com

2 內部方法調用

我們在日常開發中,經常需要在一個方法中調用另外一個方法,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    public void test() {        async("test");    }    @Async    public void async(String value) {        log.info("async:{}", value);    }}

這個示例中,在UserService類中的test()方法中調用了async()方法。8xK28資訊網——每日最新資訊28at.com

如果在controller中@Autowired了UserService類的對象,調用了它的test()方法,則async()異步的功能會失效。8xK28資訊網——每日最新資訊28at.com

我們知道Spring通過@Async注解實現異步的功能,底層其實是通過Spring的AOP實現的,也就是說它需要通過JDK動態代理或者cglib,生成代理對象。8xK28資訊網——每日最新資訊28at.com

異步的功能,是在代理對象中增加的,我們必須調用代理對象的test()方法才行。8xK28資訊網——每日最新資訊28at.com

而在類中直接進行方法的內部調用,在test()方法中調用async()方法,調用的是該類原對象的async方法,相當于調用了this.async()方法,而并非UserService代理類的async()方法。8xK28資訊網——每日最新資訊28at.com

因此,像這種內部方法調用,@Async注解的異步功能會失效。8xK28資訊網——每日最新資訊28at.com

3 方法非public

在Java中有4種權限修飾符8xK28資訊網——每日最新資訊28at.com

  • public:所有類都可以訪問。
  • private:只能同一個類訪問。
  • protected:同一個類,同一個包下的其他類,不同包下的子類可以訪問。
  • 默認修飾符:同一個類,同一個包下的其他類可以訪問。

在實際工作中,我們使用頻率最高的可能是public和private了。8xK28資訊網——每日最新資訊28at.com

如果我在定義Service類中的某個方法時,有時把權限修飾符定義錯了,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    private void async(String value) {        log.info("async:{}", value);    }}

這個例子中將UserService類的async()方法的權限修飾符定義成了private的,這樣@Async注解也會失效。8xK28資訊網——每日最新資訊28at.com

因為private修飾的方法,只能在UserService類的對象中使用。8xK28資訊網——每日最新資訊28at.com

而@Async注解的異步功能,需要使用Spring的AOP生成UserService類的代理對象,該代理對象沒法訪問UserService類的private方法,因此會出現@Async注解失效的問題。8xK28資訊網——每日最新資訊28at.com

4 方法返回值錯誤

我們在寫一個新的方法時,經常需要定義方法的返回值。8xK28資訊網——每日最新資訊28at.com

返回值可以是void、int、String、User等等,但如果返回值定義錯誤,也可能會導致@Async注解的異步功能失效。8xK28資訊網——每日最新資訊28at.com

例如:8xK28資訊網——每日最新資訊28at.com

@Servicepublic class UserService {    @Async    public String async(String value) {        log.info("async:{}", value);        return value;    }}

UserService類的async方法的返回值是String,這種情況竟然會導致@Async注解的異步功能失效。8xK28資訊網——每日最新資訊28at.com

在AsyncExecutionInterceptor類的invoke()方法,會調用它的父類AsyncExecutionAspectSupport中的doSubmit方法,該方法時異步功能的核心代碼,如下:8xK28資訊網——每日最新資訊28at.com

圖片圖片8xK28資訊網——每日最新資訊28at.com

從圖中看出,@Async注解的異步方法的返回值,要么是Future,要么是null。8xK28資訊網——每日最新資訊28at.com

因此,在實際項目中,如果想要使用@Async注解的異步功能,相關方法的返回值必須是void或者Future。8xK28資訊網——每日最新資訊28at.com

5 方法用static修飾了

有時候,我們的方法會使用static修飾,這樣在調用的地方,可以直接使用類名.方法名,訪問該方法了。8xK28資訊網——每日最新資訊28at.com

但如果在@Async方法上加了static修飾符,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public static void async(String value) {        log.info("async:{}", value);    }}

這時@Async的異步功能會失效,因為這種情況idea會直接報錯:Methods annotated with '@Async' must be overridable 。8xK28資訊網——每日最新資訊28at.com

使用@Async注解聲明的方法,必須是能被重寫的,很顯然static修飾的方法,是類的靜態方法,是不允許被重寫的。8xK28資訊網——每日最新資訊28at.com

因此這種情況下,@Async注解的異步功能會失效。8xK28資訊網——每日最新資訊28at.com

6 方法用final修飾

在Java種final關鍵字,是一個非常特別的存在。8xK28資訊網——每日最新資訊28at.com

用final修飾的類,沒法被繼承。8xK28資訊網——每日最新資訊28at.com

用final修飾的方法,沒法被重寫。8xK28資訊網——每日最新資訊28at.com

用final修飾的變量,沒法被修改。8xK28資訊網——每日最新資訊28at.com

如果final使用不當,也會導致@Async注解的異步功能失效,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    public void test() {        async("test");    }    @Async    public  final void async(String value) {        log.info("async:{}", value);    }}

這種情況下idea也會直接報錯:Methods annotated with '@Async' must be overridable 。8xK28資訊網——每日最新資訊28at.com

因為使用final關鍵字修飾的方法,是沒法被子類重寫的。8xK28資訊網——每日最新資訊28at.com

因此這種情況下,@Async注解的異步功能會失效。8xK28資訊網——每日最新資訊28at.com

7 業務類沒加@Service注解

有時候,我們在新加Service類時,會忘了加@Service注解,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j//@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:{}", value);    }}@Servicepublic class TestService {   @Autowired   private UserService userService;    public void test() {        userService.async("test");    }}

這種情況下,@Async注解異步的功能也不會生效。因為UserService類沒有使用@Service、@Component或者@Controller等注解聲明,該類不會被Spring管理,因此也就無法使用Spring的異步功能。8xK28資訊網——每日最新資訊28at.com

8 自己new的對象

在項目中,我們經常需要new一個對象,然后對他賦值,或者調用它的方法。8xK28資訊網——每日最新資訊28at.com

但如果new了一個Service類的對象,可能會出現一些意想不到的問題,例如:8xK28資訊網——每日最新資訊28at.com

@Slf4j@Servicepublic class UserService {    @Async    public void async(String value) {        log.info("async:{}", value);    }}@Servicepublic class TestService {    public void test() {        UserService userService = new UserService();        userService.async("test");    }}

在TestService類的test()方法中,new了一個UserService類的對象,然后調用該對象的async()方法。8xK28資訊網——每日最新資訊28at.com

很顯然這種情況下,async()方法只能同步執行,沒法異步執行。8xK28資訊網——每日最新資訊28at.com

因為在項目中,我們自己new的對象,不會被Spring管理,因此也就無法使用Spring的異步功能。8xK28資訊網——每日最新資訊28at.com

不過我們可以通過BeanPostProcessor類,將創建的對象手動注入到Spring容器中。8xK28資訊網——每日最新資訊28at.com

9 Spring無法掃描異步類

我們在Spring項目中可以使用@ComponentScan注解指定項目中掃描的包路徑,例如:8xK28資訊網——每日最新資訊28at.com

@ComponentScan({"com.susan.demo.service1"})@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})public class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

項目中com.susan.demo.service1這個路徑是不存在的,會導致@Async注解異步的功能失效。8xK28資訊網——每日最新資訊28at.com

同時如果@ComponentScan注解定義的路徑,沒有包含你新加的Servcie類的路徑,@Async注解異步的功能也會失效。8xK28資訊網——每日最新資訊28at.com

好了,今天的文章內容先到這里。8xK28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-87270-0.html@Async注解失效的九種場景

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 從輸入 Url 到頁面渲染的不同階段給出優化建議

下一篇: 京東:今年 618 大促活動 5 月 31 日現貨開售

標簽:
  • 熱門焦點
  • 摸魚心法第一章——和配置文件說拜拜

    為了能摸魚我們團隊做了容器化,但是帶來的問題是服務配置文件很麻煩,然后大家在群里進行了“親切友好”的溝通圖片圖片圖片圖片對比就對比,簡單對比下獨立配置中心和k8s作為配
  • 不容錯過的MSBuild技巧,必備用法詳解和實踐指南

    一、MSBuild簡介MSBuild是一種基于XML的構建引擎,用于在.NET Framework和.NET Core應用程序中自動化構建過程。它是Visual Studio的構建引擎,可在命令行或其他構建工具中使用
  • 得物效率前端微應用推進過程與思考

    一、背景效率工程隨著業務的發展,組織規模的擴大,越來越多的企業開始意識到協作效率對于企業團隊的重要性,甚至是決定其在某個行業競爭中突圍的關鍵,是企業長久生存的根本。得物
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • 東方甄選單飛:有些鳥注定是關不住的

    文/彭寬鴻編輯/羅卿東方甄選創始人俞敏洪帶隊的“7天甘肅行”直播活動已在近日順利收官。成立后一年多時間里,東方甄選要脫離抖音自立門戶的傳聞不絕于耳,“7
  • 阿里瓴羊One推出背后,零售企業迎數字化新解

    作者:劉曠近年來隨著數字經濟的高速發展,各式各樣的SaaS應用服務更是層出不窮,但本質上SaaS大多局限于單一業務流層面,對用戶核心關切的增長問題等則沒有提供更好的解法。在Saa
  • 蘋果140W USB-C充電器:采用氮化鎵技術

    據10 月 30 日 9to5 Mac 消息報道,當蘋果推出新的 MacBook Pro 2021 時,該公司還推出了新的 140W USB-C 充電器,附贈在 MacBook Pro 16 英寸機型的盒子里,也支
  • 中關村論壇11月25日開幕,15位諾獎級大咖將發表演講

    11月18日,記者從2022中關村論壇新聞發布會上獲悉,中關村論壇將于11月25至30日在京舉行。本屆中關村論壇由科學技術部、國家發展改革委、工業和信息化部、國務
Top 主站蜘蛛池模板: 温泉县| 丽江市| 乐亭县| 河北区| 肃宁县| 台北县| 新营市| 荔波县| 合肥市| 区。| 神木县| 望奎县| 龙里县| 崇礼县| 上虞市| 五指山市| 垣曲县| 炉霍县| 石嘴山市| 奉贤区| 淮阳县| 柞水县| 孙吴县| 海阳市| 伊川县| 遂平县| 太湖县| 金山区| 承德县| 盐边县| 渝中区| 林州市| 肃南| 西安市| 青州市| 仁布县| 来凤县| 峨山| 蒙阴县| 古蔺县| 昌平区|