spring-AOP 及 AOP獲取request各項參數(shù)操作
spring-AOP 及 AOP獲取request各項參數(shù)
AOP稱為面向切面編程,在程序開發(fā)中主要用來解決一些系統(tǒng)層面上的問題,比如日志,事務(wù),權(quán)限等待。
一、AOP的基本概念
Aspect
(切面):通常是一個類,里面可以定義切入點和通知JointPoint
(連接點):程序執(zhí)行過程中明確的點,一般是方法的調(diào)用Advice
(通知):AOP在特定的切入點上執(zhí)行的增強處理,有before,after,afterReturning,afterThrowing,aroundPointcut
(切入點):就是帶有通知的連接點,在程序中主要體現(xiàn)為書寫切入點表達式AOP
代理:AOP框架創(chuàng)建的對象,代理就是目標對象的加強。Spring中的AOP代理可以使JDK動態(tài)代理,也可以是CGLIB代理,前者基于接口,后者基于子類
二、Spring AOP
Spring中的AOP代理還是離不開Spring的IOC容器,代理的生成,管理及其依賴關(guān)系都是由IOC容器負責(zé),Spring默認使用JDK動態(tài)代理,在需要代理類而不是代理接口的時候,Spring會自動切換為使用CGLIB代理,不過現(xiàn)在的項目都是面向接口編程,所以JDK動態(tài)代理相對來說用的還是多一些。
三、基于注解的AOP配置方式
1.啟用@AsjectJ支持
在spring配置中配置下面一句:
<aop:aspectj-autoproxy />
或者使用注解:
@EnableAspectJAutoProxy
2.通知類型介紹
(1) Before
:在目標方法被調(diào)用之前做增強處理,@Before只需要指定切入點表達式即可
(2) AfterReturning
:在目標方法正常完成后做增強,@AfterReturning除了指定切入點表達式后,還可以指定一個返回值形參名returning,代表目標方法的返回值
(3) AfterThrowing
:主要用來處理程序中未處理的異常,@AfterThrowing除了指定切入點表達式后,還可以指定一個throwing的返回值形參名,可以通過該形參名
來訪問目標方法中所拋出的異常對象
(4) After
:在目標方法完成之后做增強,無論目標方法時候成功完成。@After可以指定一個切入點表達式
(5) Around
:環(huán)繞通知,在目標方法完成前后做增強處理,環(huán)繞通知是最重要的通知類型,像事務(wù),日志等都是環(huán)繞通知,注意編程中核心是一個ProceedingJoinPoint
3.通知執(zhí)行的優(yōu)先級
進入目標方法時,先織入Around,再織入Before,退出目標方法時,先織入Around,再織入AfterReturning,最后才織入After。
注意:Spring AOP的環(huán)繞通知會影響到AfterThrowing通知的運行,不要同時使用!同時使用也沒啥意義。
4.切入點的定義和表達式
切入點表達式的定義算是整個AOP中的核心,有一套自己的規(guī)范
Spring AOP支持的切入點指示符:
execution
:用來匹配執(zhí)行方法的連接點
A:@Pointcut(“execution(* com.aijava.springcode.service….(…))”)
第一個表示匹配任意的方法返回值,…(兩個點)表示零個或多個,上面的第一個…表示service包及其子包,第二個表示所有類,第三個*表示所有方法,第二個…表示
方法的任意參數(shù)個數(shù)
B:@Pointcut(“within(com.aijava.springcode.service.*)”)
within限定匹配方法的連接點,上面的就是表示匹配service包下的任意連接點
C:@Pointcut(“this(com.aijava.springcode.service.UserService)”)
this用來限定AOP代理必須是指定類型的實例,如上,指定了一個特定的實例,就是UserService
D:@Pointcut(“bean(userService)”)
bean也是非常常用的,bean可以指定IOC容器中的bean的名稱
下面是一個使用AOP獲取統(tǒng)計計算方法執(zhí)行時間以及獲取request請求參數(shù)等信息的log方法:
/** * description: * 統(tǒng)計請求執(zhí)行時間 * * @author wkGui */ @Component @Aspect public class ResExeTimeCounter { private static Logger logger = LoggerFactory.getLogger(ResExeTimeCounter.class); @Pointcut("execution(* com.wk.controller..*.*(..))") public void pointCut() { } @Around("pointCut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) ra; assert sra != null; HttpServletRequest request = sra.getRequest(); String url = request.getRequestURL().toString(); String method = request.getMethod(); String queryString = request.getQueryString(); long startTime = System.currentTimeMillis(); logger.info("{url:{}, method:{}, queryString:{}}", url, method, queryString); Object rs; boolean successAble = false; JsonObject paramsJson = new JsonObject(); try { Object[] params = pjp.getArgs(); for (int i = 0; i < params.length; i++) { if (params[i] instanceof BindingResult || params[i] instanceof HttpRequest || params[i] instanceof HttpResponse){ continue; } paramsJson.addProperty("param-" + i, JsonUtil.toJsonWtihNullField(params[i])); } rs = pjp.proceed(); successAble = true; } finally { logger.info("{url:{}, method:{}, success-able:{}, exe-time:{}, params:{}}", url, method, successAble, System.currentTimeMillis() - startTime, paramsJson); } return rs; } }
SpringAOP獲取request中所有參數(shù),記錄用戶操作日志
今天搞了一個AOP的管理日志,蛋疼的很....
老規(guī)矩貼代碼吧
首先除了aop的包以外需要這三個包。
自行度娘。
如果想切入controllers,請將這個代碼寫入你的mvc配置中,糾結(jié)了一上午切不進去就是這個原因.
method為你切入類的方法名
可以照這個打個模版出來,PS:無視注釋哈,逼死強迫癥
因為我的控制類里面只會有兩個參數(shù)request和response ,所以我這里request就直接等于了下標為0,
下面的
Enumeration parameter = request.getParameterNames(); while(parameter.hasMoreElements()) { String a=(String) parameter.nextElement(); System.out.println(request.getParameter(a)); }
可以獲取從頁面上傳過來的所有參數(shù)以及參數(shù)名,參數(shù):request.getParameter(a),參數(shù)名:a
上面的代碼放在aop中實測可以,但如果放在攔截器中,實測會返回一個date,不知道什么鬼,get請求的話偶爾會正常。post一定不正常,aop中無問題
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合dataworks的實現(xiàn)過程
這篇文章主要介紹了SpringBoot整合dataworks的實現(xiàn)過程,實現(xiàn)主要是編寫工具類,如果需要則可以配置成SpringBean,注入容器即可使用,需要的朋友可以參考下2022-08-08SpringBoot異步任務(wù)實現(xiàn)下單校驗庫存的項目實踐
在開發(fā)中,異步任務(wù)應(yīng)用的場景非常的廣泛,本文主要介紹了SpringBoot異步任務(wù)實現(xiàn)下單校驗庫存的項目實踐,具有一定的參考價值,感興趣的可以了解一下2023-09-09使用FormData上傳二進制文件、對象、對象數(shù)組方式
這篇文章主要介紹了使用FormData上傳二進制文件、對象、對象數(shù)組方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01關(guān)于Java8的foreach中使用return/break/continue產(chǎn)生的問題
這篇文章主要介紹了關(guān)于Java8的foreach()中使用return/break/continue產(chǎn)生的問題,在使用foreach()處理集合時不能使用break和continue這兩個方法,也就是說不能按照普通的for循環(huán)遍歷集合時那樣根據(jù)條件來中止遍歷,需要的朋友可以參考下2023-10-10Java?ASM使用logback日志級別動態(tài)切換方案展示
這篇文章主要介紹了Java?ASM使用logback日志級別動態(tài)切換方案展示,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-04-04