国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

為什么說(shuō)在SpringAOP中,不要使用This調(diào)用方法?

開(kāi)發(fā) 前端
今天,我們來(lái)聊一聊,為什么說(shuō)在AOP方法中,不要輕易使用This調(diào)用方法?

SpringAOP是Spring中除了依賴注入以外最為核心的功能,其原理是利用CGlib和JDK動(dòng)態(tài)代理等方式來(lái)實(shí)現(xiàn)運(yùn)行期動(dòng)態(tài)方法增強(qiáng),從而降低系統(tǒng)耦合,提升代碼的復(fù)用性。

不過(guò),在享受AOP強(qiáng)大功能便利的同時(shí),我們也會(huì)經(jīng)常遇到一些看起來(lái)莫名其妙的bug。

今天,我們來(lái)聊一聊,為什么說(shuō)在AOP方法中,不要輕易使用this調(diào)用方法?

使用了this會(huì)出現(xiàn)什么樣的情況?背后的原理是什么?又該如何解決??

廢話不多說(shuō),直接實(shí)戰(zhàn)上代碼。

場(chǎng)景復(fù)現(xiàn)

假設(shè)我們有一個(gè)核心支付類,其中有pay()支付功能,同時(shí)會(huì)通過(guò)record()方法記錄都有哪些用戶訪問(wèn)過(guò)這個(gè)核心功能。

@Service
public class PayService {

public void pay(){
System.out.println("執(zhí)行一些核心支付業(yè)務(wù)操作");
//記錄用戶訪問(wèn)日志
this.record();
}

public void record(){
try {
System.out.println("模擬將操作記錄投遞到日志系統(tǒng),耗時(shí)100ms");
TimeUnit.MICROSECONDS.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

隨著業(yè)務(wù)的不斷擴(kuò)大,我們需要統(tǒng)計(jì)一下保存訪問(wèn)日志這個(gè)動(dòng)作的耗時(shí)情況,看看是否會(huì)對(duì)核心支付功能有較大的影響。

所以,我們使用SpringAOP進(jìn)行了切面處理。

@Aspect
@Component
public class LogAspect {

@Around(value = "execution(* com.shishan.demo2023.service.PayService.record()) )")
public Object record(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long begin = System.currentTimeMillis();
Object proceed = proceedingJoinPoint.proceed();
System.out.println("記錄日志耗時(shí):" + (System.currentTimeMillis() - begin));
return proceed;
}
}

切面類很簡(jiǎn)單,通過(guò)@Around方法對(duì)record方法進(jìn)行切入切出,并記錄該方法的執(zhí)行時(shí)間。

?看起來(lái)很完美是不是?

老代碼不用改動(dòng),只需新增一個(gè)切面就可以實(shí)現(xiàn)新的需求。

我們新建一個(gè)controller,看看我們的切面類有沒(méi)有生效。

@RestController
@RequestMapping(value = "/demo")
public class DemoController {

@Resource
private PayService payService;

@RequestMapping(value = "/pay")
public ResponseEntity<Object> pay(){
this.payService.pay();
return ResponseEntity.ok().build();
}
}

啟動(dòng)服務(wù),訪問(wèn)
http://localhost:8080/demo/pay。

問(wèn)題出現(xiàn)了。

按照上面的代碼,在打印完業(yè)務(wù)日志之后,應(yīng)該打印一行記錄日志耗時(shí)的日志。然而控制臺(tái)卻空空如也,說(shuō)明我們的切面類并沒(méi)有生效。

?為什么定義的切面沒(méi)有執(zhí)行呢?

問(wèn)題就出現(xiàn)在pay()方法中的this調(diào)用上。?

我們可以看到,圖中的this指向的是一個(gè)普通的PayService對(duì)象,而不是被Spring增強(qiáng)后的bean。

而SpringAOP起作用的原理是什么:Spring通過(guò)JDK動(dòng)態(tài)代理和CGlib代理對(duì)目標(biāo)類生成一個(gè)代理類,在代理類中做功能增強(qiáng)。

我們看一下在controller中的PayService:

可以看到,在controller中的payService是一個(gè)被SpringCLlib增強(qiáng)后的代理類,而我們通過(guò)this引用到的,對(duì)于Spring來(lái)說(shuō)只是一個(gè)普通的bean對(duì)象,自然無(wú)法實(shí)現(xiàn)AOP的功能。

那Spring在什么時(shí)候會(huì)對(duì)一個(gè)對(duì)象進(jìn)行代理呢?

Spring會(huì)在一個(gè)bean創(chuàng)建的時(shí)候判斷是否要進(jìn)行代理,核心類是
AnnotationAwareAspectJAutoProxyCreator,其本質(zhì)是一個(gè)BeanPostProcessor。當(dāng)需要使用到AOP時(shí),它會(huì)把創(chuàng)建的原始的Bean對(duì)象wrap成代理對(duì)象作為Bean返回。

所以,最終結(jié)論是:只有被動(dòng)態(tài)代理出來(lái)的對(duì)象,才可以被Spring增強(qiáng),具備AOP的能力。

解決辦法

既然問(wèn)題找到了,那么如何解決因?yàn)閠his調(diào)用帶來(lái)的AOP失效的問(wèn)題呢?

有兩種辦法。

一,自己引用自己

直接在當(dāng)前類中注入自己,這樣Spring會(huì)對(duì)類中的屬性進(jìn)行代理,生成一個(gè)payService代理類。

需要注意的是,這樣其實(shí)是人為的制造了循環(huán)依賴。在高版本的Springboot中,循環(huán)依賴是默認(rèn)關(guān)閉的。如果想開(kāi)啟循環(huán)依賴,需要配置
spring.main.allow-circular-references=true。

二,通過(guò)AopContext

AopContext內(nèi)部維護(hù)了一個(gè)保存proxy的ThreadLocal,簡(jiǎn)單說(shuō)就是通過(guò)一個(gè)ThreadLocal將proxy和當(dāng)前線程綁定起來(lái),這樣就可以隨時(shí)拿出當(dāng)前線程綁定的 Proxy。

如果使用這樣的方式,需要在@EnableAspectJAutoProxy 里加一個(gè)配置項(xiàng) exposeProxy = true。

通過(guò)方式一修改下代碼,看看AOP是否生效。

可以看到,成功的打印出來(lái)日志耗時(shí)的log。

總結(jié)

SpringAOP實(shí)際上會(huì)自動(dòng)為我們創(chuàng)建一個(gè)Proxy,使得調(diào)用者能無(wú)感知地調(diào)用指定方法,本質(zhì)上就是一個(gè)動(dòng)態(tài)代理。我們只有訪問(wèn)這些代理對(duì)象的方法,才能獲得AOP實(shí)現(xiàn)的功能,所以通過(guò)this引用是無(wú)法去正確使用 AOP 功能的。

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2024-02-20 22:13:49

SQL語(yǔ)句編程

2017-07-03 13:33:42

AndroidItemDecorat

2014-11-21 10:50:26

JavaString

2011-03-08 12:59:38

proftpd

2023-11-29 09:19:00

WebhookURL

2012-05-24 10:29:54

編程程序員

2010-05-11 10:29:06

Unix awk

2014-05-19 15:52:57

Apache StraApache

2011-04-14 09:30:15

集合框架

2024-01-03 08:15:35

Executors線程池線程

2013-09-27 11:33:57

交換機(jī)技術(shù)Vlan技術(shù)

2024-01-24 11:24:03

C++編程異常處理

2014-04-25 10:05:42

OpenStack私有云公共云

2023-09-21 09:00:00

Merge Que開(kāi)發(fā)工具Mergify

2014-01-03 10:59:34

2015-06-11 09:59:36

數(shù)據(jù)中心UPS

2023-03-06 08:01:25

structGo語(yǔ)言

2021-12-24 17:01:29

Linux工具系統(tǒng)

2024-01-01 08:57:55

ODBCSqlServer數(shù)據(jù)庫(kù)

2025-07-28 01:00:00

調(diào)用函數(shù)CALL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

米奇777超碰欧美日韩亚洲| 国产盗摄女厕一区二区三区| 欧美精品免费在线观看| 在线中文字幕-区二区三区四区| 亚洲尤物在线视频观看| 黄色福利视频网站| 国产日产欧美一区二区三区| 老汉色影院首页| 国产一二精品视频| 水蜜桃亚洲精品| 亚洲国产综合在线看不卡| 国产精品日韩专区| 亚州综合一区| 国产精品久久91| 蜜桃一区二区三区| 国产精品久久久久久av福利软件| 国产一区二区精品福利地址| 日本精品久久久久久久| 激情av综合| 日产精品99久久久久久| 婷婷精品在线| 2019中文字幕在线| 国产中文字幕一区二区三区| 国产成人中文字幕| 欧美日一区二区三区在线观看国产免| 国产在线观看精品一区二区三区| 久久一区91| 视频一区不卡| 国产盗摄一区二区三区| 久久久久久久久久久99| 久久久www成人免费无遮挡大片| 欧美日韩第二页| 欧美激情一二三区| 在线国产小视频| 欧美日韩综合不卡| 不卡的av影片| 欧美精品videos| 精品美女久久久| 国产91aaa| 日韩不卡一区二区三区| 热这里只有精品| 国产精品欧美极品| 超碰在线公开超碰在线| 亚洲欧美日韩人成在线播放| 国产视频二区在线观看| 日韩欧美一级二级三级久久久| 精品欧美一区二区三区在线观看| 久久精品国产成人| 五月天综合网站| 一区二区冒白浆视频| 久久麻豆一区二区| yw193.com尤物在线| 亚洲男人天天操| 国内精品伊人久久久| 久草一区二区| 99久久99久久精品免费观看| 无圣光视频在线观看| 精品人在线二区三区| 欧美人与性动交xxⅹxx| 欧美激情va永久在线播放| 国产免费av一区二区三区| 激情久久av| 成人高清视频免费观看| 手机福利视频欧美| 欧美一级高清片在线观看| 日韩一区二区三区精品| 亚洲xxx视频| 国产成人在线电影| 青青九九免费视频在线| 中文字幕无线精品亚洲乱码一区| 精品在线播放| 在线观看亚洲视频啊啊啊啊| 亚洲福中文字幕伊人影院| av不卡高清| 成人中文字幕在线观看| 国产精品2024| 亚洲图片123| 色阁综合伊人av| 中文在线播放一区二区| 欧美午夜性生活| 欧美一区二区观看视频| 红杏aⅴ成人免费视频| 成人免费网站www网站高清| 色综合老司机第九色激情| 91精品国产调教在线观看| 日韩精品xxxx| 欧美日韩在线不卡| 国产精品亚洲二区| 国产一区一区三区| 欧洲av在线精品| 一区二区三区四区视频免费观看 | 在线观看三级网站| 亚洲va欧美va国产va天堂影院| 九色porny自拍视频在线观看 | 免费99视频| 亚洲女子a中天字幕| 久热在线观看视频| 亚洲成在人线av| 国产专区一区| 在线视频xx| 久久久久久久久久久av| 蜜桃av噜噜一区| 最新在线你懂的| 91wwwcom在线观看| 成人毛片在线观看| 国产高清中文字幕在线| 国产精品久久久久久久久婷婷| 一个色妞综合视频在线观看| www999久久| 屁屁影院ccyy国产第一页| 亚洲国产免费av| 在线亚洲国产精品网站| 黄色片免费在线| 国产精品日韩欧美| 国产精品国产成人国产三级| 91蜜桃臀久久一区二区| 黄色一级视频在线播放| 中文字幕在线精品| 蜜芽一区二区三区| 黄网站免费在线播放| 国产精品入口免费| 五月激情综合婷婷| 精品国产乱码久久久久久果冻传媒| 日本一极黄色片| 日韩一区二区三区在线播放| 成人网在线免费视频| 成人女同在线观看| 欧美日韩国产精品一卡| 在线观看日韩毛片| 中国av一区| 妞干网在线视频| 91国语精品自产拍在线观看性色 | 久久久久久久久免费视频| 51成人做爰www免费看网站| 亚洲一区二区三区四区五区中文 | 久久久精品久久久久| 国产酒店精品激情| 久久亚洲人体| 青青草精品视频在线| 久久久爽爽爽美女图片| 国产午夜精品一区二区| 亚洲日本va中文字幕| 成人综合av| 国产精品视频一区二区三区四 | 精品日韩一区二区三区免费视频| 日韩电影免费在线| segui88久久综合| 日韩国产精品一区二区三区| 日韩成人在线视频观看| 国产在线精品一区二区不卡了 | 国产精品免费在线 | 日韩视频一二三| 亚洲丁香久久久| 福利91精品一区二区三区| 国模视频一区| 成人影院在线观看视频| 日本最新高清不卡中文字幕| 亚洲精品中文字幕乱码三区 | 韩国精品美女www爽爽爽视频| 亚洲精品视频免费观看| 第一社区sis001原创亚洲| 第一页在线观看| 日本黄色片一级片| 欧美另类在线观看| 亚洲电影一级黄| 免费在线成人| 国产精品毛片久久久久久久久久99999999| 五月婷婷六月合| 91中文字幕在线| 亚洲久久久久久久久久久| 99热在这里有精品免费| 日韩极品少妇| 新版中文在线官网| 男人揉女人奶房视频60分 | 国产中文字幕日韩| 日韩欧美一二区| 国产不卡在线视频| 日本亚洲不卡| 免费电影网站在线视频观看福利| 免费国产黄色网址| 成人免费看黄网站| 亚洲国产精品字幕| 成人免费在线播放| 日韩电影免费看| 99热.com| 成人国产精品一级毛片视频| 高清视频在线www色| 免费亚洲一区二区| 久久精品国产精品亚洲| 亚洲一卡二卡三卡四卡五卡| 99伊人成综合| 综合欧美精品| 米奇精品一区二区三区| 日本网站免费在线观看| 国产欧美一区二区三区不卡高清| 国产一区二区黄| 欧美精品少妇一区二区三区| 国产午夜精品久久久久久免费视| 欧美二区视频| 激情小说亚洲图片|