如何手寫一個攔截器呢。假設我現在需要一個計時攔截器,我想把每一次呼叫服務鎖花費的時間列印到控制檯,我該怎麼做呢?
攔截機制有三種:
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));
}
}
複製程式碼
程式碼解釋:
- 其中,preHandle()方法再controller 呼叫之前被呼叫
- postHandle()在controller 呼叫之後被呼叫,如果有異常則不呼叫
- 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 進行註冊。
介紹下我的所有文集:
流行框架
SpringCloud springboot nginx redis
底層實現原理:
Java NIO教程 Java reflection 反射詳解 Java併發學習筆錄 Java Servlet教程 jdbc元件詳解 Java NIO教程 Java語言/版本 研究