一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - SpringAop @Around執(zhí)行兩次的原因及解決

SpringAop @Around執(zhí)行兩次的原因及解決

2021-10-15 11:38石頭剪刀布_ Java教程

這篇文章主要介紹了SpringAop @Around執(zhí)行兩次的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在使用AOP環(huán)繞通知做日志處理的時(shí)候,發(fā)現(xiàn)@Around方法執(zhí)行了兩次,雖然這里環(huán)繞通知本來(lái)就會(huì)執(zhí)行兩次,但是正常情況下是在切點(diǎn)方法前執(zhí)行一次,切點(diǎn)方法后執(zhí)行一次,但是實(shí)際情況卻是,切點(diǎn)方法前執(zhí)行兩次,切點(diǎn)方法后執(zhí)行兩次。

文字不好理解,還是寫一下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    logger.debug("==========Request log==========");
    long startTime = System.currentTimeMillis();
    Object ob = pjp.proceed();
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    //JSONObject ipInfo = JSONObject.fromObject(URLDecoder.decode(WebUtils.getCookie(request,"IP_INFO").getValue(),"utf-8"));
    //logger.debug("IP: {}", ipInfo.get("ip"));
    //logger.debug("CITY {}", ipInfo.get("city"));
    logger.debug("IP: {}", BlogUtil.getClientIpAddr(request));
    logger.debug("REQUEST_URL: {}", request.getRequestURL().toString());
    logger.debug("HTTP_METHOD: {}", request.getMethod());
    logger.debug("CLASS_METHOD: {}", pjp.getSignature().getDeclaringTypeName() + "."
            + pjp.getSignature().getName());
    //logger.info("參數(shù) : " + Arrays.toString(pjp.getArgs()));
    logger.debug("USE_TIME: {}", System.currentTimeMillis() - startTime);
    logger.debug("==========Request log end==========");
    return ob;
}

然后刷新一下頁(yè)面,得到的日志如下:

可以看到,雖然只刷新了一次,但是卻輸出了兩次日志,是不應(yīng)該的。然后通過(guò)斷點(diǎn)調(diào)試發(fā)現(xiàn),是因?yàn)樵?code>Controller中使用了@ModelAttribute

?
1
2
3
4
5
@ModelAttribute
public void counter(Model model) {
    counter.setCount(counter.getCount() + 1);
    model.addAttribute("count", counter.getCount());
}

@ModelAttribute注解的方法會(huì)在Controller方法執(zhí)行之前執(zhí)行一次,并且我將它放在了Controller中,并且攔截的是所有Controller中的方法,

這樣就導(dǎo)致了:

1、首先頁(yè)面請(qǐng)求到Controller,執(zhí)行@ModelAttribute標(biāo)注的方法,此時(shí)會(huì)被AOP攔截到一次。

2、執(zhí)行完@ModelAttribute標(biāo)注的方法后,執(zhí)行@RequestMapping標(biāo)注的方法,又被AOP攔截到一次。

所以,會(huì)有兩次日志輸出。

解決辦法:

1、將Controller中的@ModelAttribute方法,提取出來(lái),放到@ControllerAdvice中。

2、對(duì)AOP攔截規(guī)則添加注解匹配,例如:

?
1
execution(public * com.blog.controller.*.*(..)) && (@annotation(org.springframework.web.bind.annotation.RequestMapping))
?
1
&& (@annotation(org.springframework.web.bind.annotation.RequestMapping

表明這樣只會(huì)攔截RequestMappping標(biāo)注的方法。

注意:

如果是一個(gè)方法a()調(diào)用同一個(gè)類中的方法b(),如果對(duì)方法a()做攔截的話,AOP只會(huì)攔截到a(),而不會(huì)攔截到b(),因?yàn)榘?code>a()對(duì)b()的調(diào)用是通過(guò)this.b()調(diào)用的,而AOP正真執(zhí)行的是生成的代理類,通過(guò)this自然無(wú)法攔截到方法b()了。

了解Spring @Around使用及注意

注意:

1、Spring 切面注解的順序

  • @before
  • @Around( 要代理的方法執(zhí)行在其中)
  • @AfterReturning
  • @after

2、沒(méi)有@Around,則 要代理的方法執(zhí)行 異常才會(huì)被@AfterThrowing捕獲;

3、在@Around如何執(zhí)行 要代理的方法執(zhí)行

?
1
2
3
4
5
6
7
8
9
10
11
@Around("execution(* cn.com.xalead.spring.MeInterface.*(..)) || execution(* cn.com.xalead.spring.KingInterface.*(..))")
public Object test(ProceedingJoinPoint proceeding) {
    Object o = null;
    try {
        //執(zhí)行
        o = proceeding.proceed(proceeding.getArgs());
    } catch (Throwable e) {
        e.printStackTrace();
    }
    return o;
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/wxgxgp/article/details/82526311

延伸 · 閱讀

精彩推薦
  • Java教程Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進(jìn)去或缺失數(shù)據(jù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個(gè)非常實(shí)用的Java程序代碼片段

    20個(gè)非常實(shí)用的Java程序代碼片段

    這篇文章主要為大家分享了20個(gè)非常實(shí)用的Java程序片段,對(duì)java開(kāi)發(fā)項(xiàng)目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實(shí)現(xiàn)搶紅包功能

    Java實(shí)現(xiàn)搶紅包功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)搶紅包功能,采用多線程模擬多人同時(shí)搶紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級(jí)IDEA后Lombok不能使用的解決方法

    升級(jí)IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級(jí),尋思已經(jīng)有好久沒(méi)有升過(guò)級(jí)了。升級(jí)完畢重啟之后,突然發(fā)現(xiàn)好多錯(cuò)誤,本文就來(lái)介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個(gè)注意事項(xiàng)

    Java8中Stream使用的一個(gè)注意事項(xiàng)

    最近在工作中發(fā)現(xiàn)了對(duì)于集合操作轉(zhuǎn)換的神器,java8新特性 stream,但在使用中遇到了一個(gè)非常重要的注意點(diǎn),所以這篇文章主要給大家介紹了關(guān)于Java8中S...

    阿杜7472021-02-04
  • Java教程xml與Java對(duì)象的轉(zhuǎn)換詳解

    xml與Java對(duì)象的轉(zhuǎn)換詳解

    這篇文章主要介紹了xml與Java對(duì)象的轉(zhuǎn)換詳解的相關(guān)資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關(guān)于小米推送Java代碼,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧...

    富貴穩(wěn)中求8032021-07-12
主站蜘蛛池模板: 成全动漫视频在线观看 | 精品一区二区三区在线播放 | 99热这里只有精品免费 | 涩涩五月天 | 国产一区二区精品久久91 | 九九影院午夜理论片无码 | 青青青手机视频在线观看 | 四虎永久免费地址 | 热99精品视频 | 国产精品成人免费观看 | xxxxxx国产精品视频 | 白丝爆动漫羞羞动漫软件 | 1024国产看片在线观看 | 希望影院高清免费观看视频 | 俺去俺也在线www色官网 | 99久久精品免费看国产四区 | 放荡护士玩3p口述 | 国产理论片在线观看 | 国产亚洲欧美日韩俺去了 | 大色综合 | 特黄未满14周岁毛片 | 久久两性视频 | 成人欧美一区在线视频在线观看 | 日韩在线天堂免费观看 | 亚洲国产韩国欧美在线不卡 | 九九精品视频一区二区三区 | 国产精品青青青高清在线 | 国产精品成人扳一级aa毛片 | 男人的天堂va | 日本哺乳期网站xxxx | 亚洲高清无在码在线电影 | 免费aⅴ在线 | 大学生情侣在线 | 天天综合天天综合色在线 | 免费日本在线视频 | 美女口述又粗又大感觉 | 欧美精品日韩一区二区三区 | 九二淫黄大片看片 | 国产高清国内精品福利色噜噜 | 无码乱人伦一区二区亚洲一 | xvideoscom极品肌肉警察 |