SpringBoot 手寫攔截器

微笑面對生活發表於2018-04-08

如何手寫一個攔截器呢。假設我現在需要一個計時攔截器,我想把每一次呼叫服務鎖花費的時間列印到控制檯,我該怎麼做呢?

攔截機制有三種:

1. 過濾器(Filter)能拿到http請求,但是拿不到處理請求方法的資訊。
2. 攔截器(Interceptor)既能拿到http請求資訊,也能拿到處理請求方法的資訊,但是拿不到方法的引數資訊。
3. 切片(Aspect)能拿到方法的引數資訊,但是拿不到http請求資訊。

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

攔截機制圖

好了下面開始正文。

手寫攔截器實戰


/**
 * Time 時間攔截器(比時間過濾器準))
 * Created by Fant.J.
 */
@Component
public class TimeInterceptor  implements HandlerInterceptor {
    //controller 呼叫之前被呼叫
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        System.out.println("preHandle");

        System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
        System.out.println(((HandlerMethod)handler).getMethod().getName());
        httpServletRequest.setAttribute("startTime",System.currentTimeMillis());
        return true;
    }

    //controller 呼叫之後被呼叫,如果有異常則不呼叫
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

        System.out.println("postHandle");

        long startTime = (long) httpServletRequest.getAttribute("startTime");
        System.out.println("時間攔截器耗時:"+(System.currentTimeMillis() -startTime));
    }

    //controller 呼叫之後被呼叫,有沒有異常都會被呼叫,Exception 引數裡放著異常資訊
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion");
        long startTime = (long) httpServletRequest.getAttribute("startTime");
        System.out.println("時間攔截器耗時:"+(System.currentTimeMillis() -startTime));
    }
}

複製程式碼

程式碼解釋:

  1. 其中,preHandle()方法再controller 呼叫之前被呼叫
  2. postHandle()在controller 呼叫之後被呼叫,如果有異常則不呼叫
  3. afterCompletion()在controller 呼叫之後被呼叫,有沒有異常都會被呼叫,Exception 引數裡放著異常資訊。

但是值寫這個處理攔截器還不行,還需要進一步的配置,請看下面一段程式碼:

/**
 * 引入第三方過濾器 將其放入spring容器
 * Created by Fant.J.
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

//    注入Time 攔截器
    @Autowired
    private TimeInterceptor timeInterceptor;
    //新增攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //往攔截器註冊器裡新增攔截器
        registry.addInterceptor(timeInterceptor);
    }

複製程式碼

首先我們繼承WebMvcConfigurerAdapter類,重寫它的addInterceptors()方法,該方法是新增攔截器至Spring容器中。 然後呼叫攔截器註冊器InterceptorRegistry 進行註冊。

SpringBoot 手寫攔截器

介紹下我的所有文集:

流行框架

SpringCloud springboot nginx redis

底層實現原理:

Java NIO教程 Java reflection 反射詳解 Java併發學習筆錄 Java Servlet教程 jdbc元件詳解 Java NIO教程 Java語言/版本 研究

相關文章