如何手寫一個(gè)攔截器呢钥星。假設(shè)我現(xiàn)在需要一個(gè)計(jì)時(shí)攔截器村怪,我想把每一次調(diào)用服務(wù)鎖花費(fèi)的時(shí)間打印到控制臺(tái)斤葱,我該怎么做呢召廷?
攔截機(jī)制有三種:
1. 過濾器(Filter)能拿到http請求,但是拿不到處理請求方法的信息雾叭。
2. 攔截器(Interceptor)既能拿到http請求信息悟耘,也能拿到處理請求方法的信息,但是拿不到方法的參數(shù)信息织狐。
3. 切片(Aspect)能拿到方法的參數(shù)信息暂幼,但是拿不到http請求信息。
他們?nèi)齻€(gè)各有優(yōu)缺點(diǎn)赚瘦,需要根據(jù)自己的業(yè)務(wù)需求來選擇最適合的攔截機(jī)制粟誓。
好了下面開始正文。
手寫攔截器實(shí)戰(zhàn)
/**
* Time 時(shí)間攔截器(比時(shí)間過濾器準(zhǔn)))
* Created by Fant.J.
*/
@Component
public class TimeInterceptor implements HandlerInterceptor {
//controller 調(diào)用之前被調(diào)用
@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 調(diào)用之后被調(diào)用起意,如果有異常則不調(diào)用
@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("時(shí)間攔截器耗時(shí):"+(System.currentTimeMillis() -startTime));
}
//controller 調(diào)用之后被調(diào)用鹰服,有沒有異常都會(huì)被調(diào)用,Exception 參數(shù)里放著異常信息
@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("時(shí)間攔截器耗時(shí):"+(System.currentTimeMillis() -startTime));
}
}
代碼解釋:
- 其中,preHandle()方法再controller 調(diào)用之前被調(diào)用
- postHandle()在controller 調(diào)用之后被調(diào)用揽咕,如果有異常則不調(diào)用
- afterCompletion()在controller 調(diào)用之后被調(diào)用悲酷,有沒有異常都會(huì)被調(diào)用,Exception 參數(shù)里放著異常信息。
但是值寫這個(gè)處理攔截器還不行亲善,還需要進(jìn)一步的配置设易,請看下面一段代碼:
/**
* 引入第三方過濾器 將其放入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容器中顿肺。
然后調(diào)用攔截器注冊器InterceptorRegistry 進(jìn)行注冊。
介紹下我的所有文集:
流行框架
SpringCloud
springboot
nginx
redis
底層實(shí)現(xiàn)原理:
Java NIO教程
Java reflection 反射詳解
Java并發(fā)學(xué)習(xí)筆錄
Java Servlet教程
jdbc組件詳解
Java NIO教程
Java語言/版本 研究