filter、interceptor、aspect應如何選擇

前言

小夥伴們應該據說過過濾器、攔截器、切面,印象上都可以起到截斷攔截的做用,在作一些業務需求時,不知道如何選擇,今天老顧就來介紹一下他們之間的區別。程序員

Filter過濾器

過濾器能夠攔截到方法的請求和響應(ServletRequest request, ServletResponse response),並對請求響應作出過濾操做。web

過濾器依賴於servlet容器。在實現上,基於函數回調,它能夠對幾乎全部請求進行過濾,一個過濾器實例只能在容器初始化時調用一次。面試

使用過濾器的目的是用來作一些過濾操做,獲取咱們想要獲取的數據,好比:在過濾器中修改字符編碼;在過濾器中修改HttpServletRequest的一些參數,包括:過濾低俗文字、危險字符等。redis

話很少說,先上代碼sql

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

再定義兩個Controller,一個UserController,一個OrderController數據庫

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

雖然Filter過濾器和Controller請求都已經定義了,但如今過濾器是不起做用的。須要把Filter配置一下,有兩個方案編程

第一個方案在Filter上面加上@Component緩存

@Component
public class TimeFilter implements Filter

第二個方案配置化註冊過濾器tomcat

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

第二個方案的特色就是能夠細化到過濾哪些規則的URL安全

咱們來啓動應用時,過濾器被初始化了,init函數被回調

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

請求http://localhost:9000/order/1

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

看看控制檯的日誌輸出

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

請求http://localhost:9000/user/1

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

控制檯日誌輸出

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

中止應用後,控制檯輸出

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

Filter隨web應用的啓動而啓動,只初始化一次,隨web應用的中止而銷燬。

1.啓動服務器時加載過濾器的實例,並調用init()方法來初始化實例;

2.每一次請求時都只調用方法doFilter()進行處理

3.中止服務器時調用destroy()方法,銷燬實例。

咱們再來看看doFilter方法

doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

從參數咱們看到,filter裏面是可以獲取到請求的參數和響應的數據;但此方法是沒法知道是哪個Controller類中的哪一個方法被執行。

還有一點須要注意的是,filter中是無法使用注入的bean的,也就是沒法使用@Autowired

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

上面代碼注入的值爲null。這是爲何呢

其實Spring中,web應用啓動的順序是:listener->filter->servlet,先初始化listener,而後再來就filter的初始化,再接着纔到咱們的dispathServlet的初始化,所以,當咱們須要在filter裏注入一個註解的bean時,就會注入失敗,由於filter初始化時,註解的bean還沒初始化,無法注入。

若是必定你要使用,須要作一些處理,能夠私信老顧哦

Interceptor攔截器

依賴於web框架,在SpringMVC中就是依賴於SpringMVC框架。在實現上,基於Java的反射機制,屬於面向切面編程(AOP)的一種運用,就是在一個方法前,調用一個方法,或者在方法後,調用一個方法。

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

在WebMvcConfigurationSupport配置一下

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

執行結果

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

咱們發現攔截器中能夠獲取到Controller對象

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

object handler就是controller方法對象

HandlerMethod handlerMethod = (HandlerMethod)handler;
handlerMethod.getBean().getClass().getName(); //獲取類名
handlerMethod.getMethod().getName(); //獲取方法名

但咱們發現獲取不到方法的參數值,這個是爲何呢?在DispatcherServlet類中,方法

doDispatch(HttpServletRequest request, HttpServletResponse response)

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

applyPreHandle這個方法執行,就是執行的攔截器的preHandler方法,但這個過程當中,controller方法沒有從request中獲取請求參數,組裝方法參數;而是在ha.handle這個方法的時候,纔會組裝參數

雖然無法獲得方法的參數,可是能夠得到IOC的bean哦。

再說明一點的是postHandler方法

postHandler方法的執行,當controller內部有異常,posthandler方法是不會執行的。

afterCompletion方法,無論controller內部是否有異常,都會執行此方法;此方法還會有個Exception ex這個參數;若是有異常,ex會有異常值;沒有異常 此值爲null

注意點若是controller內部有異常,但異常被@ControllerAdvice 異常統一捕獲的話,ex也會爲null

Aspect切片

AOP操做能夠對操做進行橫向的攔截,最大的優點在於他能夠獲取執行方法的參數,對方法進行統一的處理。常見使用日誌,事務,請求參數安全驗證

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

上面的代碼中,咱們是能夠獲取方法的參數的

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

雖然切面aop能夠拿到方法參數,但拿不到response,request對象。

總結

咱們這裏來總結一下過濾器、攔截器、Aspect,看看區別

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

若是三者方式同時採用,那他們的執行順序是什麼呢?

filter -> interceptor -> ControllerAdvice -> aspect -> controller

返回值順序,或異常返回順序

controller -> aspect -> controllerAdvice -> Interceptor -> Filter

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

用一個圖描述一下執行順序

阿里二面:filter、interceptor、aspect應如何選擇?不少人中招

 

小夥伴們能夠根據自身業務,和上面技術的各自特色,去選擇相應的技術。今天老顧就介紹到這裏,謝謝!!!


---End---

最近老顧上傳了微服務網關的分享課程,請你們多多支持

推薦閱讀

一、學習Lambda表達式看這篇就夠了,不會讓你失望的哦(續篇)

二、Lambda用在哪裏?幾種場景?

三、爲何會出現Lambda表達式,你知道嗎?

四、不說「分佈式事務」理論,直接上大廠阿里的解決方案,絕對實用

五、女程序員問到這個問題,讓我思考了半天,Mysql的「三高」架構

六、大廠二面:CAP原則爲何只能知足其中兩項?而不能同時知足

七、阿里P7二面:聊聊零拷貝的原理

八、秒殺系統的核心點都在這裏,快來取

九、你瞭解如何利用token方式實現分佈式Session嗎?

十、Mysql索引結構演變,爲何最終會是那個結構呢?讓你一看就懂

十一、一場比賽涉及到的知識,用通俗易通的方式介紹併發協調

十二、企業實戰Redis全方面思考,你思考了嗎?

1三、面試題:Thread的start和run的區別

1四、面試題:什麼是CAS?CAS的做用以及缺點

1五、如何訪問redis中的海量數據?避免事故產生

1六、如何解決Redis熱點問題?以及如何發現熱點?

1七、如何設計API接口,實現統一格式返回?

1八、你真的知道在生產環境下如何部署tomcat嗎?

1九、分享一線互聯網大廠分佈式惟一ID設計 之 snowflake方案

20、分享大廠分佈式惟一ID設計方案,快來圍觀

2一、你想了解一線大廠的分佈式惟一ID生成方案嗎?

2二、你知道如何處理大數據量嗎?(數據拆分篇)

2三、如何永不遷移數據和避免熱點? 根據服務器指標分配數據量(揭祕篇)

2四、你知道怎麼分庫分表嗎?如何作到永不遷移數據和避免熱點嗎?

2五、你瞭解大型網站的頁面靜態化嗎?

2六、你知道如何更新緩存嗎?如何保證緩存和數據庫雙寫一致性?

2七、你知道怎麼解決DB讀寫分離,致使數據不一致問題嗎?

2八、DB讀寫分離狀況下,如何解決緩存和數據庫不一致性問題?

2九、你真的知道怎麼使用緩存嗎?

30、如何利用鎖,防止緩存擊穿?重構思想的重要性

3一、海量訂單產生的業務高峯期,如何避免消息的重複消費?

3二、你知道如何保障生產端100%消息投遞成功嗎?

3三、微服務下的分佈式session該如何管理?

相關文章
相關標籤/搜索