如何手寫一個切片呢。假設我現在需要一個計時切片,我想把每一次調用服務鎖花費的時間列印到控制台,該怎麼做呢?
攔截機制有三種:
1.
過濾器(Filter)能拿到http請求,但是拿不到處理請求方法的資訊。
2.
攔截器(Interceptor)既能拿到http請求資訊,也能拿到處理請求方法的資訊,但是拿不到方法的參數資訊。
3.
切片(Aspect)能拿到方法的參數資訊,但是拿不到http請求資訊。
他們三個各有優缺點,需要根據自己的業務需求來選擇最适合的攔截機制。
攔截機制圖
好了下面開始正文。
寫一個切片就比較簡單了,可以直接用現成的幾個注解
- @Before() //相當于攔截器的 preHandle
- @After() //相當于postHandle
- @AfterThrowing //相當于afterCompletion如果出現異常
- @Around() 包括以上三點,是以一般使用它(簡潔)
TimeAspect .java
/**
* 時間切片類 (比攔截器好,能拿到具體參數)
* Created by Fant.J.
*/
@Aspect
@Component
public class TimeAspect {
@Around("execution(* com.laojiao.securitydemo.controller.UserController.*(..))") //第一個* 表示任何傳回值 第二個* 表示任何方法
public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable { //pjp是一個 包含攔截方法資訊的對象
System.out.println("time aspect start");
//參數數組
Object[] args = pjp.getArgs();
for (Object arg:args){
System.out.println("arg is :" +arg);
}
long start = System.currentTimeMillis();
//調用被攔截的方法
Object object = pjp.proceed();
System.out.println("time aspect 耗時:"+(System.currentTimeMillis() - start));
System.out.println("time aspect end");
return object;
}
}
代碼解釋:
-
第一個* 表示任何傳回值 第二個* 表示任何方法@Around("execution(* com.laojiao.securitydemo.controller.UserController.*(..))")
- ProceedingJoinPoint (pjp)是一個 包含攔截方法資訊的對象
-
調用被攔截的方法pjp.proceed();
介紹下我的所有文集:
流行架構
SpringCloud springboot nginx redis底層實作原理:
Java NIO教程 Java reflection 反射詳解 Java并發學習筆錄 Java Servlet教程 jdbc元件詳解 Java語言/版本 研究