1. 程式人生 > 其它 >SpringBoot interceptor實踐總結

SpringBoot interceptor實踐總結

技術標籤:工作總結攔截器多個攔截器攔截器執行順序

目錄

一interceptor是什麼

二interceptor的作用

三 interceptor的實現


一interceptor是什麼

在軟體開發領域中,攔截器模式是一種軟體設計模式。

二interceptor的作用

你覺得 interceptor 解決了什麼問題呢?從實踐的經驗來看,攔截器核心提供了兩種能力:複用和擴充套件

怎麼理解複用?

假設客戶端呼叫我們服務端介面,而服務端所有介面都會對 appId 進行校驗,這個 appId 是頒發給客戶端的,來標識客戶端身份。由於需要對 appId 進行校驗,所有的介面都需要加上 appId 校驗程式碼。

這樣是不是很不優雅?而且 appId 校驗程式碼是與業務無關的,直接寫在接口裡面是不是有很大的侵入性呢?使用攔截器,appId 校驗程式碼只需要做一次,業務程式碼更專注於業務邏輯,程式碼變得優雅。

怎麼理解擴充套件?

假設我們這塊有新的需求,需要對一些介面進行 token 認證,如何快速支援需求且對程式碼的侵入性小呢?新增 token 認證攔截器就好了;

過兩天說需要對一些介面列印請求日誌,我們這塊只需要新增日誌攔截器就好。

你看攔截器能如此快速、靈活解決業務需求,真是一個好東西哈。

三 interceptor的實現

實踐中我們這塊以 appId 攔截器和 token 認證攔截器來具體實現。SpringBoot 的攔截器實現和 SpringMVC 一致,通過配置把攔截器注入到 Spring 容器中去,只是配置方式不一樣,這塊以 SpringBoot 來實現。

3.1 攔截器類

@Component
public class AppIdInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //業務邏輯。。。
		System.out.println("AppIdInterceptor preHandle");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("AppIdInterceptor postHandle");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("AppIdInterceptor afterCompletion");
	}
}
@Component
public class AuthenticateInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //業務邏輯。。。
		System.out.println("AuthenticateInterceptor preHandle");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("AuthenticateInterceptor postHandle");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("AuthenticateInterceptor afterCompletion");
	}
}

3.2 配置類

將 appId 攔截器和 token 認證攔截器加入到攔截器佇列。

@Configuration
public class InterceptorAdapter implements WebMvcConfigurer {

	@Resource
	private AppIdInterceptor appIdInterceptor;

	@Resource
	private AuthenticateInterceptor authenticateInterceptor;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(appIdInterceptor).addPathPatterns("/**");
        registry.addInterceptor(authenticateInterceptor).addPathPatterns("/api/getById");
	}
}

addPathPatterns("/**") :表示攔截所有路徑;addPathPatterns("/api/getById") :只攔截 “/api/getById” 這個路徑。

是否需要考慮多個攔截器的載入順序呢?

我覺得是需要的,就拿上面的 appId 攔截器和 token 認證攔截器來說,appId 攔截器是攔截所有的,必須在前面;而 token 認證攔截器是部分介面需要的,應該在後面。

總結來說就是,越是具有普適性、覆蓋面廣的攔截器越應該先載入,反倒是那些定製化、覆蓋面小的攔截器應該後加載。

多個攔截器內部是怎樣的執行順序呢?

總結:

1 preHandle 按攔截器定義順序呼叫。

2 postHandler 按攔截器定義逆序呼叫。

3 afterCompletion按攔截器定義逆序呼叫。

4 postHandler 在攔截器鏈內所有攔截器返成功呼叫。

5 afterCompletion 只有 preHandle 返回 true 才呼叫。