spring aop之@AfterReturning不生效問(wèn)題及解決
spring aop之@AfterReturning不生效
長(zhǎng)話短說(shuō),我其他的都已經(jīng)檢查過(guò)了,連@Before都能成功執(zhí)行,@AfterReturning就是不執(zhí)行。
后經(jīng)檢查,是我@AfterReturning中returning的問(wèn)題,我設(shè)置的是:
@Pointcut("execution(public * com.xxx.xxx.xx.xxx.controller.*.*(..))")
public void request() {}
@AfterReturning(returning = "result", value = "request()")
public void after(Result result){
// 具體邏輯
}Result 是項(xiàng)目中公共的返回對(duì)象,里面包含 code、body等等,大同小異。
其中SaveToInsetSql()切入點(diǎn)表達(dá)式的方法,經(jīng)檢查,是可以確定到具體的攔截方法的。
按道理,這樣是沒(méi)問(wèn)題的,我反復(fù)的檢查,也百度了半天,始終沒(méi)解決問(wèn)題,在這兒搗鼓了半天,最終讓我發(fā)現(xiàn)了問(wèn)題,就是這個(gè)Result出了問(wèn)題
確實(shí),我們接口返回的都是響應(yīng)體都是Result的json格式, 但是呢,并不一定Controller的返回值就是Result,而是項(xiàng)目中通過(guò)org.springframework.web.method.support.HandlerMethodReturnValueHandler來(lái)包裝了返回體的,當(dāng)然如果controller返回值本身就是Result,就不用再包裝。
我一直習(xí)慣了在controller返回業(yè)務(wù)的具體返回值而不是經(jīng)過(guò)包裝的Result,所以忘了這茬。
Aop的執(zhí)行,是先于org.springframework.web.method.support.HandlerMethodReturnValueHandler的,所以在正常返回通知中,根據(jù)returning指定的是Result,而controller本身返回又是List、String等業(yè)務(wù)返回值,兩者匹配不上,就一直不生效。
總之:
正常反正通知中配置的 目標(biāo)方法返回值 與 真實(shí)的目標(biāo)方法返回值 無(wú)法匹配(相同或多態(tài)),導(dǎo)致正常返回通知無(wú)法執(zhí)行。
AOP @AfterReturning的使用
1.首先引入依賴(lài)
<!--spring AOP的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>2.定義一個(gè)注解作為切點(diǎn)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogInfo {
String value() default "";
}3.寫(xiě)aop實(shí)現(xiàn)
@Aspect
@Component
@Slf4j
public class LogInfoAspect {
/**
* 配置切點(diǎn) 切點(diǎn)為注解 意為有該注解的地方日志生效
*/
@Pointcut("@annotation(com.example.myproject.annoation.LogInfo)")
public void pointcut() { }
/**
* 定義切點(diǎn),返回值為user,要與下面方法中的入?yún)⒚鹵ser保持一致
* returning的是獲取到要提取日志的方法的返回值
*/
@AfterReturning(pointcut = "pointcut()",returning = "user")
public void afterReturning(Object user){
User user1 = (User) user;
log.info("用戶(hù)Id為:" + user1.getUserId());
log.info("用戶(hù)名稱(chēng)為:" + user1.getUserName());
}
}4.寫(xiě)測(cè)試接口
/**
* aop測(cè)試
* 這里的user類(lèi)和aop實(shí)現(xiàn)類(lèi)中定義的returning值 User 保持一致,這樣aop中才能正確讀取到返回值
* @param
* @return
*/
@LogInfo
@PostMapping("/aopTest")
public String aopTest(@RequestBody User user){
return user.getUserName();
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot+Redis+Lua防止IP重復(fù)防刷攻擊的方法
本文主要介紹了SpringBoot+Redis+Lua防止IP重復(fù)防刷攻擊的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
解決@FeignClient注入service失敗問(wèn)題
這篇文章主要介紹了解決@FeignClient注入service失敗問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot遇到的坑@Qualifier報(bào)紅的解決
這篇文章主要介紹了SpringBoot遇到的坑@Qualifier報(bào)紅的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
在SpringBoot項(xiàng)目中實(shí)現(xiàn)給所有請(qǐng)求加固定前綴
這篇文章主要介紹了在SpringBoot項(xiàng)目中實(shí)現(xiàn)給所有請(qǐng)求加固定前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
淺談java+內(nèi)存分配及變量存儲(chǔ)位置的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談java+內(nèi)存分配及變量存儲(chǔ)位置的區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08
SpringBoot2入門(mén)自動(dòng)配置原理及源碼分析
這篇文章主要為大家介紹了SpringBoot2入門(mén)自動(dòng)配置原理及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

