一文搞懂過濾器丹允、攔截器的區(qū)別

過濾器(Filter)

過濾器的實(shí)現(xiàn)

直接實(shí)現(xiàn)filter接口航瞭,也可以通過@WebFilter注解實(shí)現(xiàn)對(duì)特定的URL攔截
package com.example.filter;


import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author 米斯特白
 */
@Component
public class MyFilter implements Filter {
    /**
     * 該方法在容器啟動(dòng)初始化過濾器時(shí)被調(diào)用彤恶,
     * 它在 Filter 的整個(gè)生命周期只會(huì)被調(diào)用一次钞钙。
     *「注意」:這個(gè)方法必須執(zhí)行成功,否則過濾器會(huì)不起作用声离。
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter 前置");
    }

    /**
     * 容器中的每一次請(qǐng)求都會(huì)調(diào)用該方法芒炼, FilterChain 用來調(diào)用下一個(gè)過濾器 Filter。
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        System.out.println("Filter 處理中");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    /**
     * 當(dāng)容器銷毀 過濾器實(shí)例時(shí)調(diào)用該方法术徊,一般在方法中銷毀或關(guān)閉資源本刽,
     * 在過濾器 Filter 的整個(gè)生命周期也只會(huì)被調(diào)用一次
     */
    @Override
    public void destroy() {
        System.out.println("Filter 后置");
    }
}

攔截器 (Interceptor)

一個(gè)應(yīng)用中可以同時(shí)存在多個(gè)攔截器Interceptor, 一個(gè)請(qǐng)求也可以觸發(fā)多個(gè)攔截器弧关,
而每個(gè)攔截器的調(diào)用會(huì)依據(jù)它的聲明順序依次執(zhí)行。

攔截器實(shí)現(xiàn)

package com.example.filter;

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;

/**
 *
 *
 * @author 米斯特白
 */
@Component
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 在請(qǐng)求處理之前進(jìn)行調(diào)用唤锉。
     *【注意】:如果該方法的返回值是false世囊,視為當(dāng)前請(qǐng)求結(jié)束,不僅自身的攔截器會(huì)失效窿祥,還會(huì)導(dǎo)致其他攔截器也不再執(zhí)行株憾。
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Interceptor 前置");
        return true;
    }


    /**
     * 只有在preHandle()方法返回true時(shí)才會(huì)執(zhí)行。會(huì)在controller中的方法調(diào)用之后,dispatcherServlet返回視圖渲染之前被調(diào)用嗤瞎。
     *【有意思的是】 postHandle()方法的調(diào)用順序跟 preHandle()正好是相反的墙歪,先聲明的攔截器preHandle() 方法先執(zhí)行,
     * 而 postHandle方法反而會(huì)后執(zhí)行贝奇。
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor 處理中");
    }

    /**
     * 之后再preHandle()方法返回值為true時(shí)才會(huì)執(zhí)行虹菲,在整個(gè)請(qǐng)求結(jié)束之后,DispatcherServlet渲染了對(duì)應(yīng)的視圖之后執(zhí)行掉瞳。
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Interceptor 后置");
    }
}

攔截器配置

package com.example.config;

import com.example.filter.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author 米斯特白
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /**
     * 配置攔截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

過濾器和攔截器都體現(xiàn)了AOP思想毕源,都可以實(shí)現(xiàn)比如日志記錄,登錄權(quán)限等功能陕习,但是二者的不同點(diǎn)也是比較多的霎褐。

過濾器和攔截器的區(qū)別

1.實(shí)現(xiàn)原理不同

過濾器是基于回調(diào)函數(shù)的
攔截器是基于Java的反射機(jī)制(動(dòng)態(tài)代理)實(shí)現(xiàn)的
【重點(diǎn)】過濾器
在我們定義的filter中都會(huì)實(shí)現(xiàn)一個(gè)doFilter()方法,這個(gè)方法有一個(gè)filterChain參數(shù)该镣,實(shí)際上它是
一個(gè)回調(diào)接口冻璃。
ApplicationFilterChain是它的一個(gè)實(shí)現(xiàn)類,這個(gè)實(shí)現(xiàn)類也有一個(gè)doFilter()方法就是回調(diào)方法损合。
ApplicationFilterChain能拿到我們自定義的filter類省艳,其內(nèi)部回調(diào)方法doFilter()里
會(huì)調(diào)用各個(gè)自定義的xxxFilter過濾器,并執(zhí)行doFilter()方法塌忽。
而每個(gè)xxxFilter 會(huì)先執(zhí)行自身的 doFilter() 過濾邏輯拍埠,最后在執(zhí)行結(jié)束前會(huì)執(zhí)行
filterChain.doFilter(servletRequest, servletResponse),
也就是回調(diào)ApplicationFilterChain的doFilter() 方法土居,以此循環(huán)執(zhí)行實(shí)現(xiàn)函數(shù)回調(diào)枣购。
public interface FilterChain {
    void doFilter(ServletRequest var1, ServletResponse var2) 
                                                 [圖片上傳中...(未命名文件.png-672b65-1653919111382-0)]
throws IOException, ServletException;
}
未命名文件.png

ApplicationFilterChain拿到我們自定義的filter,執(zhí)行doFilter方法調(diào)用各個(gè)自定義的doFilter()方法擦耀。

而每個(gè)自定義的filter會(huì)先執(zhí)行自己的doFilter()邏輯棉圈,在執(zhí)行結(jié)束之前執(zhí)行filterChain.dofilter(servletRequest, servletResponse),也就是回調(diào)ApplicationFilterChain的doFilter()方法,ApplicationFilterChain的獲取下一個(gè)filter眷蜓,繼續(xù)循環(huán)執(zhí)行分瘾。

2、使用范圍不同

filter是servlet中的規(guī)范吁系,也就是說filter的使用依賴于Tomcat等web容器德召,所以它只能在web程序中使用,
而攔截器(Intercepter)它是一個(gè)spring組件汽纤,并由spring容器管理上岗、,并不依賴于Tomcat等容器蕴坪,
是可以單獨(dú)使用的肴掷。不僅在web程序中可以使用敬锐,在application,Swing等程序中也可以使用呆瞻。

3台夺、觸發(fā)時(shí)機(jī)不同

image.png
過濾器filter是在請(qǐng)求容器之后,但是在進(jìn)入servlet之前進(jìn)行預(yù)處理痴脾,請(qǐng)求結(jié)束是在servlet處理完之后颤介。
攔截器Interceptor是在請(qǐng)求進(jìn)入servlet之后,在controller之前進(jìn)行預(yù)處理明郭,
controller中渲染了對(duì)應(yīng)的視圖之后請(qǐng)求結(jié)束买窟。

4、攔截的請(qǐng)求范圍不同
我們配置好了攔截器和過濾器薯定,下邊我們看一下他們的請(qǐng)求范圍始绍。

D:\developTool\jdk1.8\bin\java.exe -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:64029,suspend=y,server=n -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -javaagent:C:\Users\米斯特白\AppData\Local\Temp\captureAgentjars\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\developTool\jdk1.8\jre\lib\charsets.jar;D:\developTool\jdk1.8\jre\lib\deploy.jar;D:\developTool\jdk1.8\jre\lib\ext\access-bridge-64.jar;D:\developTool\jdk1.8\jre\lib\ext\cldrdata.jar;D:\developTool\jdk1.8\jre\lib\ext\dnsns.jar;D:\developTool\jdk1.8\jre\lib\ext\jaccess.jar;D:\developTool\jdk1.8\jre\lib\ext\jfxrt.jar;D:\developTool\jdk1.8\jre\lib\ext\localedata.jar;D:\developTool\jdk1.8\jre\lib\ext\nashorn.jar;D:\developTool\jdk1.8\jre\lib\ext\sunec.jar;D:\developTool\jdk1.8\jre\lib\ext\sunjce_provider.jar;D:\developTool\jdk1.8\jre\lib\ext\sunmscapi.jar;D:\developTool\jdk1.8\jre\lib\ext\sunpkcs11.jar;D:\developTool\jdk1.8\jre\lib\ext\zipfs.jar;D:\developTool\jdk1.8\jre\lib\javaws.jar;D:\developTool\jdk1.8\jre\lib\jce.jar;D:\developTool\jdk1.8\jre\lib\jfr.jar;D:\developTool\jdk1.8\jre\lib\jfxswt.jar;D:\developTool\jdk1.8\jre\lib\jsse.jar;D:\developTool\jdk1.8\jre\lib\management-agent.jar;D:\developTool\jdk1.8\jre\lib\plugin.jar;D:\developTool\jdk1.8\jre\lib\resources.jar;D:\developTool\jdk1.8\jre\lib\rt.jar;F:\workspaces\springboot-redis\target\classes;D:\developTool\mavenRepository\.m2\repository\redis\clients\jedis\3.3.0\jedis-3.3.0.jar;D:\developTool\mavenRepository\.m2\repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\commons\commons-pool2\2.11.1\commons-pool2-2.11.1.jar;D:\developTool\mavenRepository\.m2\repository\com\alibaba\fastjson\1.2.78\fastjson-1.2.78.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-data-redis\2.6.1\spring-boot-starter-data-redis-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter\2.6.1\spring-boot-starter-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.6.1\spring-boot-starter-logging-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\ch\qos\logback\logback-classic\1.2.7\logback-classic-1.2.7.jar;D:\developTool\mavenRepository\.m2\repository\ch\qos\logback\logback-core\1.2.7\logback-core-1.2.7.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.14.1\log4j-to-slf4j-2.14.1.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\logging\log4j\log4j-api\2.14.1\log4j-api-2.14.1.jar;D:\developTool\mavenRepository\.m2\repository\org\slf4j\jul-to-slf4j\1.7.32\jul-to-slf4j-1.7.32.jar;D:\developTool\mavenRepository\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\developTool\mavenRepository\.m2\repository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\data\spring-data-redis\2.6.0\spring-data-redis-2.6.0.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\data\spring-data-keyvalue\2.6.0\spring-data-keyvalue-2.6.0.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\data\spring-data-commons\2.6.0\spring-data-commons-2.6.0.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-tx\5.3.13\spring-tx-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-oxm\5.3.13\spring-oxm-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-aop\5.3.13\spring-aop-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-context-support\5.3.13\spring-context-support-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\io\lettuce\lettuce-core\6.1.5.RELEASE\lettuce-core-6.1.5.RELEASE.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-common\4.1.70.Final\netty-common-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-handler\4.1.70.Final\netty-handler-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-resolver\4.1.70.Final\netty-resolver-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-buffer\4.1.70.Final\netty-buffer-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-codec\4.1.70.Final\netty-codec-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\netty\netty-transport\4.1.70.Final\netty-transport-4.1.70.Final.jar;D:\developTool\mavenRepository\.m2\repository\io\projectreactor\reactor-core\3.4.12\reactor-core-3.4.12.jar;D:\developTool\mavenRepository\.m2\repository\org\reactivestreams\reactive-streams\1.0.3\reactive-streams-1.0.3.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.6.1\spring-boot-starter-web-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.6.1\spring-boot-starter-json-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.13.0\jackson-databind-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.0\jackson-annotations-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.13.0\jackson-core-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.0\jackson-datatype-jdk8-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.0\jackson-datatype-jsr310-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.0\jackson-module-parameter-names-2.13.0.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.6.1\spring-boot-starter-tomcat-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.55\tomcat-embed-core-9.0.55.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.55\tomcat-embed-el-9.0.55.jar;D:\developTool\mavenRepository\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.55\tomcat-embed-websocket-9.0.55.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-web\5.3.13\spring-web-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-beans\5.3.13\spring-beans-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-webmvc\5.3.13\spring-webmvc-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-context\5.3.13\spring-context-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-expression\5.3.13\spring-expression-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-devtools\2.6.1\spring-boot-devtools-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot\2.6.1\spring-boot-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.6.1\spring-boot-autoconfigure-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-configuration-processor\2.6.1\spring-boot-configuration-processor-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;D:\developTool\mavenRepository\.m2\repository\mysql\mysql-connector-java\8.0.16\mysql-connector-java-8.0.16.jar;D:\developTool\mavenRepository\.m2\repository\com\alibaba\druid\1.2.3\druid-1.2.3.jar;D:\developTool\mavenRepository\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;D:\developTool\mavenRepository\.m2\repository\com\baomidou\mybatis-plus-boot-starter\3.4.2\mybatis-plus-boot-starter-3.4.2.jar;D:\developTool\mavenRepository\.m2\repository\com\baomidou\mybatis-plus\3.4.2\mybatis-plus-3.4.2.jar;D:\developTool\mavenRepository\.m2\repository\com\baomidou\mybatis-plus-extension\3.4.2\mybatis-plus-extension-3.4.2.jar;D:\developTool\mavenRepository\.m2\repository\com\baomidou\mybatis-plus-core\3.4.2\mybatis-plus-core-3.4.2.jar;D:\developTool\mavenRepository\.m2\repository\com\baomidou\mybatis-plus-annotation\3.4.2\mybatis-plus-annotation-3.4.2.jar;D:\developTool\mavenRepository\.m2\repository\com\github\jsqlparser\jsqlparser\4.0\jsqlparser-4.0.jar;D:\developTool\mavenRepository\.m2\repository\org\mybatis\mybatis\3.5.6\mybatis-3.5.6.jar;D:\developTool\mavenRepository\.m2\repository\org\mybatis\mybatis-spring\2.0.5\mybatis-spring-2.0.5.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\boot\spring-boot-starter-jdbc\2.6.1\spring-boot-starter-jdbc-2.6.1.jar;D:\developTool\mavenRepository\.m2\repository\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-jdbc\5.3.13\spring-jdbc-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-core\5.3.13\spring-core-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\org\springframework\spring-jcl\5.3.13\spring-jcl-5.3.13.jar;D:\developTool\mavenRepository\.m2\repository\com\suyeer\mybatis-plus\3.2.0.6\mybatis-plus-3.2.0.6.jar;D:\developTool\mavenRepository\.m2\repository\org\eclipse\yasson\1.0.5\yasson-1.0.5.jar;D:\developTool\mavenRepository\.m2\repository\jakarta\json\bind\jakarta.json.bind-api\1.0.2\jakarta.json.bind-api-1.0.2.jar;D:\developTool\mavenRepository\.m2\repository\jakarta\json\jakarta.json-api\1.1.6\jakarta.json-api-1.1.6.jar;D:\developTool\mavenRepository\.m2\repository\org\glassfish\jakarta.json\1.1.5\jakarta.json-1.1.5-module.jar;D:\developTool\idea\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar" com.example.SpringbootRedisApplication
Connected to the target VM, address: '127.0.0.1:64029', transport: 'socket'
14:24:22.822 [Thread-1] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@609aea86

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.1)

2022-05-30 14:24:23.327  INFO 16376 --- [  restartedMain] com.example.SpringbootRedisApplication   : Starting SpringbootRedisApplication using Java 1.8.0_281 on 米斯特白 with PID 16376 (F:\workspaces\springboot-redis\target\classes started by 米斯特白 in F:\workspaces\springboot-redis)
2022-05-30 14:24:23.331  INFO 16376 --- [  restartedMain] com.example.SpringbootRedisApplication   : No active profile set, falling back to default profiles: default
2022-05-30 14:24:23.387  INFO 16376 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-05-30 14:24:23.388  INFO 16376 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-05-30 14:24:24.113  INFO 16376 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2022-05-30 14:24:24.115  INFO 16376 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2022-05-30 14:24:24.142  INFO 16376 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 Redis repository interfaces.
2022-05-30 14:24:24.736  INFO 16376 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2022-05-30 14:24:24.745  INFO 16376 --- [  restartedMain] o.a.coyote.http11.Http11NioProtocol      : Initializing ProtocolHandler ["http-nio-8080"]
2022-05-30 14:24:24.746  INFO 16376 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-05-30 14:24:24.746  INFO 16376 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.55]
2022-05-30 14:24:24.840  INFO 16376 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-05-30 14:24:24.840  INFO 16376 --- [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1452 ms
Filter 前置
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.4.2 
2022-05-30 14:24:26.103  WARN 16376 --- [  restartedMain] c.b.m.core.metadata.TableInfoHelper      : Can not find table primary key in Class: "com.example.pojo.User".
2022-05-30 14:24:26.847  INFO 16376 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-05-30 14:24:26.862  INFO 16376 --- [  restartedMain] o.a.coyote.http11.Http11NioProtocol      : Starting ProtocolHandler ["http-nio-8080"]
2022-05-30 14:24:26.878  INFO 16376 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-05-30 14:24:26.898  INFO 16376 --- [  restartedMain] com.example.SpringbootRedisApplication   : Started SpringbootRedisApplication in 4.066 seconds (JVM running for 6.028)
2022-05-30 14:25:20.540  INFO 16376 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-05-30 14:25:20.541  INFO 16376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2022-05-30 14:25:20.542  INFO 16376 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
Filter 處理中
Interceptor 前置
Interceptor 處理中
Interceptor 后置

Process finished with exit code 130

我們發(fā)現(xiàn),過濾器的init()方法话侄,隨著容器的啟動(dòng)進(jìn)行了初始化亏推。
然后,控制臺(tái)打印的日志是:

Filter 處理中
Interceptor 前置
Interceptor 處理中
Interceptor 后置

5年堆、注入Bean情況不同

在實(shí)際的業(yè)務(wù)場景中吞杭,應(yīng)用到過濾器或攔截器,為處理業(yè)務(wù)邏輯難免會(huì)引入一些service服務(wù)变丧。
在攔截器中注入service芽狗,發(fā)起請(qǐng)求測試一下 ,報(bào)錯(cuò)了痒蓬,debug跟一下發(fā)現(xiàn)注入的service是Null
這是因?yàn)榧虞d順序?qū)е碌膯栴}童擎,攔截器加載的時(shí)間點(diǎn)在springcontext之前,而Bean又是由spring進(jìn)行管理攻晒。

解決方案

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Bean
    public MyInterceptor getMyInterceptor() {
        System.out.println("注入MyInterceptor到spring容器");
        return new MyInterceptor();
    }

    /**
     * 配置攔截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/**");
    }
}

6顾复、控制執(zhí)行順序不同

實(shí)際開發(fā)過程中,會(huì)出現(xiàn)多個(gè)過濾器或攔截器同時(shí)存在的情況鲁捏,不過芯砸,有時(shí)我們希望某個(gè)過濾器或攔截器能優(yōu)先執(zhí)行,就涉及到它們的執(zhí)行順序给梅。

過濾器用@Order注解控制執(zhí)行順序假丧,通過@Order控制過濾器的級(jí)別,值越小級(jí)別越高越先執(zhí)行动羽。
攔截器默認(rèn)的執(zhí)行順序包帚,就是它的注冊(cè)順序,也可以通過Order手動(dòng)設(shè)置控制曹质,值越小越先執(zhí)行婴噩。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市羽德,隨后出現(xiàn)的幾起案子几莽,更是在濱河造成了極大的恐慌,老刑警劉巖宅静,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件章蚣,死亡現(xiàn)場離奇詭異,居然都是意外死亡姨夹,警方通過查閱死者的電腦和手機(jī)纤垂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磷账,“玉大人峭沦,你說我怎么就攤上這事√釉悖” “怎么了吼鱼?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绰咽。 經(jīng)常有香客問我菇肃,道長,這世上最難降的妖魔是什么取募? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任琐谤,我火速辦了婚禮,結(jié)果婚禮上玩敏,老公的妹妹穿的比我還像新娘斗忌。我一直安慰自己,他們只是感情好聊品,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布飞蹂。 她就那樣靜靜地躺著,像睡著了一般翻屈。 火紅的嫁衣襯著肌膚如雪陈哑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天伸眶,我揣著相機(jī)與錄音惊窖,去河邊找鬼。 笑死厘贼,一個(gè)胖子當(dāng)著我的面吹牛界酒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嘴秸,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼毁欣,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼庇谆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凭疮,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤饭耳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后执解,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寞肖,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年衰腌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了新蟆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡右蕊,死狀恐怖琼稻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情饶囚,我是刑警寧澤欣簇,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坯约,受9級(jí)特大地震影響熊咽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闹丐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一横殴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卿拴,春花似錦衫仑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缘挽,卻和暖如春瞄崇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背壕曼。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國打工苏研, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腮郊。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓摹蘑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轧飞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衅鹿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容