日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

@Async注解导致循环依赖,BeanCurrentlyInCreationException异常

發布時間:2023/12/10 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 @Async注解导致循环依赖,BeanCurrentlyInCreationException异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

使用@Async異步注解導致該Bean在循環依賴時啟動報BeanCurrentlyInCreationException異常的根本原因分析,以及提供解決方案

?

今天在自己項目中使用@Async的時候,碰到了一個問題:Spring循環依賴(circular reference)問題。
或許剛說到這,有的小伙伴就會大驚失色了。Spring不是解決了循環依賴問題嗎,它是支持循環依賴的呀?怎么會呢?

出現使用@Async導致循環依賴問題的必要條件:

  • 已開啟@EnableAsync的支持
  • @Async注解所在的Bean被循環依賴了
  • 為什么有小伙伴跟我說:我使用@Async即使本類方法調用也從來木有遇到這個錯誤啊?難道它不常見?
    為此經過我的一番調查,包括看一些同事、小伙伴的代碼發現:并不是使用@Async沒有啟動報錯,而是他本類調用的時候直接調用的方法,這樣@Async是不生效的但小伙伴卻全然不知而已。

    至于@Async沒生效這種問題為何沒報出來???甚至過了很久很久都沒人發現和關注??
    其實道理很簡單,它和事務不生效不一樣,@Async若沒生效99%情況下都不會影響到業務的正常進行,因為它不會影響數據正確性,只會影響到性能(無非就是異步變同步唄,這是兼容的)

    我們知道事務不生效和@Async不生效的根本原因都是同一個:直接調用了本類方法而非接口方法/代理對象方法。
    解決這類不生效問題的方案一般我們都有兩種:

    自己注入自己,然后再調用接口方法(當然此處的一個變種是使用編程方式形如:AInterface a = applicationContext.getBean(AInterface.class);這樣子手動獲取也是可行的~~~本文不討論這種比較直接簡單的方式)
    使用AopContext.currentProxy();

    讓不調用本類的@Async方法不就可以了;讓不產生循環依賴不就可以了,這也是解決方案

    1:新建一個線程池配置類AsyncConfig

    @EnableAsync @Configuration public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(10); //核心線程數executor.setMaxPoolSize(20); //最大線程數executor.setQueueCapacity(1000); //隊列大小executor.setKeepAliveSeconds(300); //線程最大空閑時間executor.setThreadNamePrefix("fsx-Executor-"); //指定用于新創建的線程名稱的前綴。executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒絕策略(一共四種,此處省略)executor.initialize();return executor;}// 異常處理器:當然你也可以自定義的,這里我就這么簡單寫了~~~@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new SimpleAsyncUncaughtExceptionHandler();} }

    ?

    ?

    2:新增一個HelloService接口

    public interface HelloService {Object hello(Integer id);void fun1(); }

    ?

    3:新增一個HelloServiceImpl實現類

    @Service public class HelloServiceImpl implements HelloService{@Autowiredprivate HelloService helloService;@Overridepublic Object hello(Integer id) {System.out.println("線程名稱:" + Thread.currentThread().getName());helloService.fun1(); // 使用接口方式調用,而不是thisreturn "service hello";}@Async@Overridepublic void fun1() {System.out.println("線程名稱:" + Thread.currentThread().getName());} }

    ?

    4:新增一個異步測試類

    @SpringBootTest public class AsyncTest {@Autowiredprivate HelloService helloService;@Testpublic void test(){helloService.hello(1);} }

    ?

    5:啟動測試類

    此種做法首先是Spring中一個典型的循環依賴場景:自己依賴自己。本以為能夠像解決事務不生效問題一樣依舊屢試不爽,但沒想到非常的不給面子,啟動即報錯

    報錯如下BeanCurrentlyInCreationException異常

    ?

    ?

    6:解決方法

    在HelloServiceImpl類上@Autowired注解下加上@Lazy注解,即懶加載

    ?

    7:啟動項目

    輸出如下,成功了

    ?

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的@Async注解导致循环依赖,BeanCurrentlyInCreationException异常的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。