天天看點

SpringBoot 手寫切片/面向切面程式設計

如何手寫一個切片呢。假設我現在需要一個計時切片,我想把每一次調用服務鎖花費的時間列印到控制台,該怎麼做呢?

攔截機制有三種:

1.

過濾器(Filter)

能拿到http請求,但是拿不到處理請求方法的資訊。

2.

攔截器(Interceptor)

既能拿到http請求資訊,也能拿到處理請求方法的資訊,但是拿不到方法的參數資訊。

3.

切片(Aspect)

能拿到方法的參數資訊,但是拿不到http請求資訊。

他們三個各有優缺點,需要根據自己的業務需求來選擇最适合的攔截機制。

SpringBoot 手寫切片/面向切面程式設計

攔截機制圖

好了下面開始正文。

寫一個切片就比較簡單了,可以直接用現成的幾個注解

  • @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語言/版本 研究