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

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

我跟你說@RefreshScope跟Spring事件監聽一起用有坑!

來源: 責編: 時間:2024-07-09 06:59:41 870觀看
導讀本文記錄一下我在 Spring 自帶的事件監聽類添加 @RefreshScope 注解時遇到的坑,原本這兩個東西單獨使用是各自安好,但當大家將它們組合在一起時,會發現我們的事件監聽代碼被重復執行。希望大家引以為鑒,避免重復踩坑。耐

本文記錄一下我在 Spring 自帶的事件監聽類添加 @RefreshScope 注解時遇到的坑,原本這兩個東西單獨使用是各自安好,但當大家將它們組合在一起時,會發現我們的事件監聽代碼被重復執行。希望大家引以為鑒,避免重復踩坑。耐心看完,你一定會有所收獲!gW528資訊網——每日最新資訊28at.com

前置描述

最近有一個用戶拉新的需求,需要在新用戶注冊時判斷用戶是否有對應的邀請關系,如果有則需要給新用戶贈送系統資源。gW528資訊網——每日最新資訊28at.com

原有的用戶注冊邏輯里使用了 Spring 自帶的事件監聽工具,也就是 applicationEventPublisher(事件發布類)以及 ApplicationListener(事件監聽類),在用戶注冊完畢寫入用戶記錄并生成 token 后,會觸發 RegisterEvent(注冊事件)的發布。偽代碼如下,gW528資訊網——每日最新資訊28at.com

// 1. 用戶注冊,寫入數據庫RegisterResponseVO registerResponseVO = memberRegisterService.register(new RegisterRequestVO(request);// 2. 生成tokenString token = getToken(memberEntity.getId(), request.getSource());log.info("login mobile {} login token {}", request.getMobile(), token);// 3. 發布注冊事件,會觸發登錄日志監聽、優惠券贈送監聽等applicationEventPublisher.publishEvent(new RegisterEvent(request, memberEntity, token));

由于之前代碼已經使用事件監聽邏輯,所以這里我們的新用戶注冊判斷邀請關系的邏輯就直接新建一個 NewUserInvitedListener 監聽類即可。偽代碼如下,gW528資訊網——每日最新資訊28at.com

@Slf4j@RefreshScope@AllArgsConstructor@Componentpublic class NewUserInvitedListener implements ApplicationListener<RegisterEvent> {    @Async("asyncServiceExecutor")    @Override    public void onApplicationEvent(RegisterEvent registerEvent) {        UserLoginRequestVO requestVO = registerEvent.getRequestVO();        MemberEntity memberEntity = registerEvent.getMemberEntity();        log.info("================ NewUserInvitedListener =============== registerEvent is {}", registerEvent);        // 1. 校驗邏輯        validateUser(memberEntity);        // 2. 判斷用戶是否有邀請關系        // 3. 如果有則贈送系統資源        ...    }}

OK,代碼邏輯也不復雜,寫完提測交給測試下班(周五下午寫完)。gW528資訊網——每日最新資訊28at.com

發現問題

周一一來,測試就在群里 @ 后端人員說是新用戶贈送的系統資源送了兩次,說實話我一開始是不太信的,直到我去查了日志,發現 NewUserInvitedListener 監聽類的日志確實被打印了兩次,也就是說我們的 NewUserInvitedListener 監聽類被觸發了兩次。gW528資訊網——每日最新資訊28at.com

OK,到這里我們的問題就確確實實產生了,接下來就是解決問題。gW528資訊網——每日最新資訊28at.com

解決思路

問題產生通常都有很多種解決方法,我們如何選擇一個最適合我們當前場景的方法才能體現出我們對業務、技術的理解。在這個監聽類重復觸發的場景里,就有多種解決方式,我簡單列舉幾個,gW528資訊網——每日最新資訊28at.com

  1. 添加冪等處理,防止重復執行
  2. 加鎖,防止重復執行
  3. 解決下為什么監聽類會重復觸發

這三個解決方案各有優劣,通過對監聽類的業務邏輯添加冪等邏輯或者加鎖邏輯都是可以解決的,但是這不是問題根源,問題根源是在于監聽類為什么會被重復觸發。在本文中,我也將帶著大家一步一步探索并解決這個問題。gW528資訊網——每日最新資訊28at.com

檢查下之前的事件監聽類是否也有重復觸發的問題

因為這個代碼是照著之前的邏輯寫的,新加的 NewUserInvitedListener 被發現重復觸發,那以前的 MemberLoginLogListener 是否也有重復觸發的問題。偽代碼如下,gW528資訊網——每日最新資訊28at.com

@Slf4j@Component@AllArgsConstructorpublic class MemberLoginLogListener implements ApplicationListener<RegisterEvent> {    private MemberLoginLogService memberLoginLogService;    @Async("asyncServiceExecutor")    @Override    public void onApplicationEvent(RegisterEvent event) {        MemberEntity memberEntity = event.getMemberEntity();        log.info("================ MemberLoginLogListener ===============, mobile is {}", memberEntity.getMobile());        MemberLoginLogEntity memberLoginLogEntity = MemberLoginLogConvertor.buildLoginLogEntity(event.getRequestVO(),                event.getMemberEntity());        memberLoginLogEntity.setToken(event.getToken());        memberLoginLogService.save(memberLoginLogEntity);    }}

查詢 MemberLoginLogListener 監聽類的日志,發現只有一次打印,說明之前寫的 MemberLoginLogListener 監聽類沒有重復觸發的問題,那這里就很奇怪了。對比一下 NewUserInvitedListener 監聽類與 MemberLoginLogListener 監聽類的差別,很明顯我們發現 NewUserInvitedListener 監聽類上多了一個 @RefreshScope 注解。gW528資訊網——每日最新資訊28at.com

OK,問題有可能就是 @RefreshScope 注解導致,我們去掉 @RefreshScope 注解在看看日志打印。gW528資訊網——每日最新資訊28at.com

去掉 @RefreshScope 注解

當我們去掉 @RefreshScope 注解后,神奇的事情發生了,NewUserInvitedListener 監聽類的日志打印正常了,只觸發了一次!OK,到這里我們也就發現了問題出在 @RefreshScope 注解上。gW528資訊網——每日最新資訊28at.com

如何搜索問題

雖然我們知道了問題出在 @RefreshScope 注解上,但是我們怎么向搜索引擎描述這個問題嘞?gW528資訊網——每日最新資訊28at.com

很多人發現了問題,但是不知道如何描述問題,怎么描述問題才能讓別人一聽就懂,從而能給你提供幫助。你需要把問題的重點描述出來,搜索引擎才能給予精準幫助。gW528資訊網——每日最新資訊28at.com

在我們這個新用戶注冊判斷邀請關系的場景里,很顯然我們的搜索詞可以是 “spring 事件監聽重復觸發 @RefreshScope”可以看到我的搜索關鍵詞有 3 個,分別是 spring、事件監聽重復觸發以及 @RefreshScope。讓我們來看看搜索結果。gW528資訊網——每日最新資訊28at.com

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

前 5 個搜索結果中,只有第五個的標題可能符合我們的搜索內容,我們點進去看一看。gW528資訊網——每日最新資訊28at.com

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

很遺憾,跟我們的問題場景并不相符,我們并沒有搜索到我們想要的東西。在這里我們的搜索關鍵詞“spring 事件監聽重復觸發 @RefreshScope”并沒有給予我們幫助。gW528資訊網——每日最新資訊28at.com

回到問題本身

既然我們的問題已經定位到了,在于 @RefreshScope 會導致監聽類的重復觸發,可是這個關鍵詞并沒有相關搜索結果,那么我們只能換個角度。gW528資訊網——每日最新資訊28at.com

為什么會重復觸發?gW528資訊網——每日最新資訊28at.com

在 NewUserInvitedListener 監聽類中,我們使用 @Component 注解,默認注冊了一個單例 bean,這個 bean 用于接收用戶注冊事件。既然 bean 是單一的,那就是說 Spring 發送了 2 次 RegisterEvent 事件嗎?結合上文提到的 MemberLoginLogListener 監聽類只觸發一次的日志,很顯然,Spring 只會發送了 1 次 RegisterEvent 事件。gW528資訊網——每日最新資訊28at.com

難道說問題在于 Spring 里出現了兩個 NewUserInvitedListener 類型的 bean?gW528資訊網——每日最新資訊28at.com

那么到這里恭喜我們終于定位到了重復觸發問題的根源。gW528資訊網——每日最新資訊28at.com

如果大家了解 @RefreshScope 的原理相信大家已經猜出來了。gW528資訊網——每日最新資訊28at.com

@RefreshScope 原理

Spring 中 @scope 注解的原理就是在創建 Scope=singleton 的 Bean 時,IOC 會保存實例在一個 Map 中,保證這個 Bean 在一個 IOC 上下文有且僅有一個實例。gW528資訊網——每日最新資訊28at.com

SpringCloud 新增了一個自定義的作用域:refresh(可以理解為“動態刷新”),同樣用了一種獨特的方式改變了 Bean 的管理方式,使得其可以通過外部化配置(.properties)的刷新,在應用不需要重啟的情況下熱加載新的外部化配置的值。gW528資訊網——每日最新資訊28at.com

這個 scope 是如何做到熱加載的呢?RefreshScope 主要做了以下動作:單獨管理 Bean 生命周期gW528資訊網——每日最新資訊28at.com

創建 Bean 的時候如果是 RefreshScope 就緩存在一個專門管理的 ScopeMap 中,這樣就可以管理 Scope 是 Refresh 的 Bean 的生命周期了(所以含 RefreshScope 的其實一共創建了兩個 bean)。gW528資訊網——每日最新資訊28at.com

重新創建 BeangW528資訊網——每日最新資訊28at.com

外部化配置刷新之后,會觸發一個動作,這個動作將上面的 ScopeMap 中的 Bean 清空,這樣這些 Bean 就會重新被 IOC 容器創建一次,使用最新的外部化配置的值注入類中,達到熱加載新值的效果。gW528資訊網——每日最新資訊28at.com

看完 @RefreshScope 的原理相信大家已經知道了出現兩個 NewUserInvitedListener 類型 bean 的原因是在于 @RefreshScope 導致。這是由于 @RefreshScope 注解的內部實現創建了另外一個相同類型的 NewUserInvitedListener bean,導致我們的新用戶監聽邏輯被重復執行。gW528資訊網——每日最新資訊28at.com

回到搜索關鍵詞

假如我是說假如,假如我們不知道 @RefreshScope 的原理,自然不知道項目中出現了兩個 NewUserInvitedListener 類型的 bean 是 @RefreshScope 導致。那么我們怎么通過搜索關鍵詞來找到這個問題嘞?gW528資訊網——每日最新資訊28at.com

到這里也就是本文的重點所在,怎么通過搜索關鍵詞來解決我們的問題。gW528資訊網——每日最新資訊28at.com

先定義問題

在這個場景里我們使用的是 Spring 項目,問題本質是 @RefreshScope 在 Spring 自帶的事件監聽類搭配使用時,由于 @RefreshScope 會導致 bean 重復進而導致重復觸發。gW528資訊網——每日最新資訊28at.com

總結關鍵詞

在上面的先定義問題中,我們提煉一下關鍵詞,gW528資訊網——每日最新資訊28at.com

  • Spring:這個關鍵詞在 Spring 項目中必帶,大家應該沒有意見把
  • @RefreshScope:我們的問題根源,搜索也得帶上
  • 生成同一個 bean:這是一個描述語句,簡要描述一下我們發現的問題

看一看搜索結果,gW528資訊網——每日最新資訊28at.com

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

點進第一個結果,gW528資訊網——每日最新資訊28at.com

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

OK,大功告成,看到我們框選中的地方了嗎,上文的 @RefreshScope 原理解釋,就是復制與這里。gW528資訊網——每日最新資訊28at.com

貼一下原文地址:https://blog.csdn.net/m0_71777195/article/details/127223544gW528資訊網——每日最新資訊28at.com

一些思考

實話實說,我在測試給我上報問題,到發現這個問題來自于 @RefreshScope 注解只用了 10 分鐘,如上文所說,我通過對比以前寫的 MemberLoginLogListener 監聽類,早早的定位到問題來自于 @RefreshScope 注解。可是到我完整修復這個問題,提交到測試環境,卻花了 2 個半小時,原因是因為我在研究這個問題的根源,這也是這篇文章的由來。gW528資訊網——每日最新資訊28at.com

假如說這個問題發生在線上,那么我根本不可能花這么多時間來研究,我需要的就是迅速解決這個問題并修復上線,避免影響更多用戶。gW528資訊網——每日最新資訊28at.com

一樣的,大家在遇到這種相似問題時,如果境況緊急出現在生產環境,大家本著對工作負責的態度,應該迅速解決并做故障復盤。如果是出現在測試環境我們可以本著對技術執著可以認真專研下這個問題。gW528資訊網——每日最新資訊28at.com

其實我還想說的是在這個問題里,我能 10 分鐘定位到問題來自于 @RefreshScope 注解,可能也有運氣成分。但是很多情況下當我們照驢子畫馬寫代碼,發現出了問題時,這種情況大部分還是我們“畫蛇添足”導致。大家可以通過對比以前代碼迅速找出問題原因。gW528資訊網——每日最新資訊28at.com

找出了問題后是如何解決問題。這篇文章里,我給大家講了講我的搜索關鍵詞心得。第一是講重點、第二是找到問題本質,這樣才能從搜索引擎嘴里找出我們想要的答案。gW528資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-99639-0.html我跟你說@RefreshScope跟Spring事件監聽一起用有坑!

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

上一篇: 有使用過vm.$set嗎,原理是什么?

下一篇: 2024 Vue 生態工具最能打的組合!

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
极品少妇一区二区三区精品视频| 免费成人网www| 一区二区高清在线观看| 一本一本a久久| 香蕉久久一区二区不卡无毒影院| 久久av资源网站| 女人天堂亚洲aⅴ在线观看| 欧美日韩国产亚洲一区| 国产精品一区二区a| 尤物yw午夜国产精品视频| 亚洲精选久久| 亚洲欧美日韩国产综合在线 | 久久综合伊人77777麻豆| 欧美精选一区| 国产午夜精品理论片a级探花| 亚洲福利在线视频| 亚洲一区免费看| 久久人人97超碰精品888| 欧美日韩一区二区三| 国产一区二区三区在线观看免费视频| 亚洲人成亚洲人成在线观看图片| 亚洲一区二区三区四区五区午夜| 久久天堂成人| 国产精品毛片va一区二区三区| 伊人久久久大香线蕉综合直播| 亚洲少妇最新在线视频| 久久天堂国产精品| 国产精品久久久久久久久久尿| 在线精品在线| 性久久久久久| 欧美日韩午夜| 一区二区亚洲精品| 亚洲欧美日本精品| 欧美日韩国产在线一区| 在线电影一区| 小辣椒精品导航| 欧美日韩精品一二三区| 亚洲二区在线视频| 久久成人精品| 国产精品vvv| 亚洲国产欧美不卡在线观看| 午夜一区二区三区不卡视频| 欧美另类在线播放| 在线播放中文字幕一区| 欧美一级在线亚洲天堂| 国产精品夫妻自拍| 亚洲精品一区二区三区樱花 | 国产精品美女久久久浪潮软件| 亚洲国产高清一区| 欧美中文在线观看| 国产精品第十页| 日韩网站在线| 免费久久99精品国产| 国产一区二区三区无遮挡| 亚洲综合日韩| 欧美视频在线视频| 日韩一区二区精品葵司在线| 免费欧美电影| 在线观看成人一级片| 久久激情综合| 国产日韩欧美一二三区| 亚洲欧美日韩国产综合精品二区| 欧美日韩国产一区精品一区 | 欧美中文字幕久久| 国产精品美女久久久久久2018| 99这里只有久久精品视频| 欧美成人四级电影| 亚洲国产精品一区二区www| 久久男人资源视频| 韩日精品在线| 久久久久在线| 激情一区二区三区| 久久婷婷一区| 在线看日韩av| 你懂的网址国产 欧美| 在线免费观看视频一区| 久久亚洲精品视频| 又紧又大又爽精品一区二区| 开心色5月久久精品| 在线看一区二区| 免费久久精品视频| 亚洲大片av| 蘑菇福利视频一区播放| 在线观看一区欧美| 欧美v日韩v国产v| 亚洲国产精品成人综合| 欧美电影打屁股sp| 亚洲狼人综合| 欧美精品久久久久久久久老牛影院 | 国产精品一区在线播放| 香蕉久久一区二区不卡无毒影院 | 亚洲无吗在线| 国产精品美女久久久久久久 | 欧美国产三级| 9国产精品视频| 欧美色视频在线| 亚洲综合电影| 国产日产亚洲精品| 久久久久久夜| 亚洲国产三级| 欧美视频在线观看一区| 香港久久久电影| 极品中文字幕一区| 欧美福利电影网| 一区二区三区国产在线| 国产精品狠色婷| 久久er精品视频| 亚洲国产高清一区| 欧美日韩亚洲高清| 亚洲欧美日韩精品久久奇米色影视| 国产视频一区欧美| 可以看av的网站久久看| 亚洲精品一二区| 国产精品久久9| 久久精品人人做人人综合| 亚洲国产成人在线视频| 欧美性猛交一区二区三区精品| 香港久久久电影| 在线观看亚洲| 欧美午夜美女看片| 久久精品国产一区二区三区免费看| 亚洲第一区色| 欧美日韩在线播放三区四区| 欧美在线免费视屏| 亚洲激情精品| 国产精品美女在线| 可以免费看不卡的av网站| 夜夜夜久久久| 黄色精品一二区| 欧美日韩国产成人在线免费| 欧美一区二视频| 亚洲日本va午夜在线影院| 国产乱码精品一区二区三区不卡 | 久久婷婷影院| 中日韩美女免费视频网站在线观看| 国产亚洲欧美日韩一区二区| 欧美福利视频在线观看| 亚洲欧美视频在线| 亚洲国产综合在线看不卡| 国产伦精品一区二区三区在线观看| 美国成人直播| 亚洲免费影视| 亚洲国产成人在线| 国产日韩av在线播放| 欧美激情bt| 久久精品日韩欧美| 亚洲一区二区三区涩| 亚洲高清资源| 国产毛片精品视频| 欧美日韩高清在线| 久久精品国亚洲| 亚洲一区二区三区成人在线视频精品| 尤物精品国产第一福利三区| 国产精品成人一区| 欧美成人亚洲成人日韩成人| 久久国产婷婷国产香蕉| 在线亚洲国产精品网站| 在线日韩av片| 国产亚洲在线| 国产精品成人在线观看| 欧美成年人视频网站| 久久福利影视| 亚洲男女自偷自拍| 亚洲理论在线| 亚洲国语精品自产拍在线观看| 国内视频一区| 国产欧美日韩视频| 国产精品老牛| 欧美色图麻豆| 欧美另类视频| 欧美成人综合一区| 久久色在线播放| 欧美在线免费观看| 午夜亚洲精品| 中文国产一区| 亚洲精品久久久久久久久久久| 激情久久五月天| 国产亚洲高清视频| 国产精品呻吟| 欧美午夜美女看片| 欧美日韩免费一区二区三区视频| 免费不卡在线视频| 久久影音先锋| 久久久成人网| 久久成人国产精品| 亚欧成人在线| 亚洲欧美日韩国产中文在线| 国产精品99久久久久久有的能看| 亚洲精品视频免费在线观看| 亚洲国产精选| 亚洲国产精品一区制服丝袜| 伊人久久大香线蕉综合热线 | 激情视频一区二区三区| 国产一区视频在线观看免费| 国产精品美女久久久浪潮软件| 欧美视频在线一区| 欧美三级日本三级少妇99| 欧美色播在线播放| 欧美性做爰毛片| 欧美丝袜一区二区三区| 欧美日韩精品欧美日韩精品 | 欧美午夜宅男影院| 国产精品久久国产精品99gif | 国产日韩欧美在线一区|