最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解

 更新時間:2022年10月17日 09:54:56   作者:Java中文社群  
過濾器(Filter)和攔截器(Interceptor)都是基于?AOP(Aspect?Oriented?Programming,面向切面編程)思想實現(xiàn)的,用來解決項目中某一類問題的兩種“工具”,但二者有著明顯的差距,接下來我們一起來看

實現(xiàn)過濾器和攔截器

首先,我們先來看一下二者在 Spring Boot 項目中的具體實現(xiàn),這對后續(xù)理解二者的區(qū)別有很大的幫助。

a) 實現(xiàn)過濾器

過濾器可以使用 Servlet 3.0 提供的 @WebFilter 注解,配置過濾的 URL 規(guī)則,然后再實現(xiàn) Filter 接口,重寫接口中的 doFilter 方法,具體實現(xiàn)代碼如下:

import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Component
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("過濾器:執(zhí)行 init 方法。");
    }
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("過濾器:開始執(zhí)行 doFilter 方法。");
        // 請求放行
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("過濾器:結(jié)束執(zhí)行 doFilter 方法。");
    }
    @Override
    public void destroy() {
        System.out.println("過濾器:執(zhí)行 destroy 方法。");
    }
}

其中:

  • void init(FilterConfig filterConfig):容器啟動(初始化 Filter)時會被調(diào)用,整個程序運行期只會被調(diào)用一次。用于實現(xiàn) Filter 對象的初始化。
  • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain):具體的過濾功能實現(xiàn)代碼,通過此方法對請求進行過濾處理,其中 FilterChain 參數(shù)是用來調(diào)用下一個過濾器或執(zhí)行下一個流程。
  • void destroy():用于 Filter 銷毀前完成相關(guān)資源的回收工作。

b) 實現(xiàn)攔截器

攔截器的實現(xiàn)分為兩步,第一步,創(chuàng)建一個普通的攔截器,實現(xiàn) HandlerInterceptor 接口,并重寫接口中的相關(guān)方法;第二步,將上一步創(chuàng)建的攔截器加入到 Spring Boot 的配置文件中。 接下來,先創(chuàng)建一個普通攔截器,實現(xiàn) HandlerInterceptor 接口并重寫 preHandle/postHandle/afterCompletion 方法,具體實現(xiàn)代碼如下:

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TestInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("攔截器:執(zhí)行 preHandle 方法。");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("攔截器:執(zhí)行 postHandle 方法。");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("攔截器:執(zhí)行 afterCompletion 方法。");
    }
}

其中:

  • boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle):在請求方法執(zhí)行前被調(diào)用,也就是調(diào)用目標方法之前被調(diào)用。比如我們在操作數(shù)據(jù)之前先要驗證用戶的登錄信息,就可以在此方法中實現(xiàn),如果驗證成功則返回 true,繼續(xù)執(zhí)行數(shù)據(jù)操作業(yè)務(wù);否則就返回 false,后續(xù)操作數(shù)據(jù)的業(yè)務(wù)就不會被執(zhí)行了。
  • void postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView):調(diào)用請求方法之后執(zhí)行,但它會在 DispatcherServlet 進行渲染視圖之前被執(zhí)行。
  • void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex):會在整個請求結(jié)束之后再執(zhí)行,也就是在 DispatcherServlet 渲染了對應(yīng)的視圖之后再執(zhí)行。

最后,我們再將上面的攔截器注入到項目配置文件中,并設(shè)置相應(yīng)攔截規(guī)則,具體實現(xiàn)代碼如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class AppConfig implements WebMvcConfigurer {

    // 注入攔截器
    @Autowired
    private TestInterceptor testInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor) // 添加攔截器
                .addPathPatterns("/*"); // 攔截所有地址
    }
}

了解了二者的使用之后,接下來我們來看二者的區(qū)別。

過濾器 VS 攔截器

過濾器和攔截器的區(qū)別主要體現(xiàn)在以下 5 點:

  • 出身不同;
  • 觸發(fā)時機不同;
  • 實現(xiàn)不同;
  • 支持的項目類型不同;
  • 使用的場景不同。

接下來,我們一一來看。

1.出身不同

過濾器來自于 Servlet,而攔截器來自于 Spring 框架,從上面代碼中我們也可以看出,過濾器在實現(xiàn)時導(dǎo)入的是 Servlet 相關(guān)的包,如下圖所示:

而攔截器在實現(xiàn)時,導(dǎo)入的是 Spring 相關(guān)的包,如下圖所示:

2.觸發(fā)時機不同

請求的執(zhí)行順序是:請求進入容器 > 進入過濾器 > 進入 Servlet > 進入攔截器 > 執(zhí)行控制器(Controller),如下圖所示:

所以過濾器和攔截器的執(zhí)行時機也是不同的,過濾器會先執(zhí)行,然后才會執(zhí)行攔截器,最后才會進入真正的要調(diào)用的方法。

3.實現(xiàn)不同

過濾器是基于方法回調(diào)實現(xiàn)的,我們在上面實現(xiàn)過濾器的時候就會發(fā)現(xiàn),當我們要執(zhí)行下一個過濾器或下一個流程時,需要調(diào)用 FilterChain 對象的 doFilter 方法進行回調(diào)執(zhí)行,如下圖所示:

由此可以看出,過濾器的實現(xiàn)是基于方法回調(diào)的。 而攔截器是基于動態(tài)代理(底層是反射)實現(xiàn)的,它的實現(xiàn)如下圖所示:

代理調(diào)用的效果如下圖所示:

4.支持的項目類型不同

過濾器是 Servlet 規(guī)范中定義的,所以過濾器要依賴 Servlet 容器,它只能用在 Web 項目中;而攔截器是 Spring 中的一個組件,因此攔截器既可以用在 Web 項目中,同時還可以用在 Application 或 Swing 程序中。

5.使用的場景不同

因為攔截器更接近業(yè)務(wù)系統(tǒng),所以攔截器主要用來實現(xiàn)項目中的業(yè)務(wù)判斷的,比如:登錄判斷、權(quán)限判斷、日志記錄等業(yè)務(wù)。 而過濾器通常是用來實現(xiàn)通用功能過濾的,比如:敏感詞過濾、字符集編碼設(shè)置、響應(yīng)數(shù)據(jù)壓縮等功能。

本文項目源碼下載

https://gitee.com/mydb/springboot-examples/tree/master/spring-boot-filter

總結(jié)

過濾器和攔截器都是基于 AOP 思想實現(xiàn)的,用來處理某個統(tǒng)一的功能的,但二者又有 5 點不同:出身不同、觸發(fā)時機不同、實現(xiàn)不同、支持的項目類型不同以及使用的場景不同。過濾器通常是用來進行全局過濾的,而攔截器是用來實現(xiàn)某項業(yè)務(wù)攔截的。

以上就是SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解的詳細內(nèi)容,更多關(guān)于SpringBoot過濾器 攔截器區(qū)別的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java中的switch case語句使用詳解

    java中的switch case語句使用詳解

    這篇文章主要介紹了java中的switch case語句使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java非遞歸實現(xiàn)刪除任意目錄的方法

    Java非遞歸實現(xiàn)刪除任意目錄的方法

    這篇文章主要為大家詳細介紹了Java非遞歸實現(xiàn)刪除任意目錄的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Mybatis中通過generator生成mapper、Dao、mapper.xml的方法

    Mybatis中通過generator生成mapper、Dao、mapper.xml的方法

    這篇文章主要介紹了Mybatis中通過generator生成mapper、Dao、mapper.xml的方法,需要的朋友可以參考下
    2017-01-01
  • Java中如何獲取文件的上級目錄

    Java中如何獲取文件的上級目錄

    這篇文章主要介紹了Java中如何獲取文件的上級目錄問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 詳解java安全編碼指南之可見性和原子性

    詳解java安全編碼指南之可見性和原子性

    java類中會定義很多變量,有類變量也有實例變量,這些變量在訪問的過程中,會遇到一些可見性和原子性的問題。這里我們來詳細了解一下怎么避免這些問題。
    2021-06-06
  • Java實例講解文件上傳與跨域問題

    Java實例講解文件上傳與跨域問題

    這篇文章主要介紹了Java文件上傳與跨域問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Java面試題沖刺第二十六天--實戰(zhàn)編程

    Java面試題沖刺第二十六天--實戰(zhàn)編程

    這篇文章主要為大家分享了最有價值的三道java實戰(zhàn)面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Spring Bean的定義及三種創(chuàng)建方式

    Spring Bean的定義及三種創(chuàng)建方式

    本文主要介紹了Spring容器獲取Bean的9種方式小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解

    MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解

    本文將為大家說說關(guān)于 #{} 和 ${},這個是 MyBatis 在面試中最常問的面試題,以及數(shù)據(jù)庫連接池相關(guān)的知識,感興趣的朋友跟隨小編一起看看吧
    2024-01-01
  • Java哈希表的概念及實現(xiàn)完整代碼

    Java哈希表的概念及實現(xiàn)完整代碼

    這篇文章主要介紹了Java哈希表的概念及實現(xiàn)的相關(guān)資料,哈希表是一種高效查找數(shù)據(jù)的結(jié)構(gòu),通過哈希函數(shù)將關(guān)鍵字映射到數(shù)組的索引位置,當發(fā)生沖突時,可以通過閉散列或開散列(鏈地址法)來解決,需要的朋友可以參考下
    2024-11-11

最新評論

潞城市| 温州市| 同德县| 隆安县| 东兰县| 广安市| 皋兰县| 博客| 棋牌| 西乌| 同仁县| 安康市| 岳普湖县| 定襄县| 临洮县| 大英县| 辉南县| 鲜城| 德州市| 清河县| 巍山| 盐亭县| 房山区| 金昌市| 鄱阳县| 巴南区| 宜宾县| 威宁| 休宁县| 吴忠市| 张家界市| 滦平县| 金山区| 德清县| 海阳市| 鲜城| 专栏| 科尔| 玉树县| 罗城| 石林|