springboot(五)——springboot中的攔截器和過濾器小結

前言

關於過濾器Filter和攔截器Interceptor,你們都不會陌生,從一開始的servelet,到springmvc,再到如今的springboot,都有接觸到,記得剛接觸的時候,會容易弄混淆,想寫這篇文章作個小的總結java

攔截器和過濾器的異同

  • 相同點
    1. 都是aop編程思想的體現,能夠在程序執行先後作一些操做,如權限操做,日誌記錄等
  • 不一樣點:
    1. Filter是Servlet規範中定義的,攔截器是Spring框架中的
    2. 觸發時機不同,過濾器是在請求進入容器後,但請求進入servlet以前進行預處理的
    3. 攔截器能夠獲取IOC容器中的各個bean,而過濾器就不行,攔截器歸Spring管理

Springboot實現過濾器和攔截器

第一步:定義Filterspring

@Slf4j
public class TestFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("TestFilter filter。。。。。。。。");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
複製代碼

第二步:注入springboot容器當中編程

@Configuration
public class FilterConfig {

    @Bean
    Filter testFilter(){
        return new TestFilter();
    }

    @Bean
    public FilterRegistrationBean<TestFilter> filterRegistrationBean1(){
        FilterRegistrationBean<TestFilter> filterRegistrationBean=new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter((TestFilter) testFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        //filterRegistrationBean.setOrder();多個filter的時候order的數值越小 則優先級越高
        return filterRegistrationBean;
    }
}
複製代碼

第三步:定義攔截器api

@Slf4j
@Service(value = "testInterceptor")
public class TestInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("TestInterceptor preHandle....");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        log.info("TestInterceptor postHandle....");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        log.info("TestInterceptor afterCompletion....");
    }

}
複製代碼

第四步:加入springboot容器springboot

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    TestInterceptor testInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(testInterceptor)
                .addPathPatterns("/api/**");
    }
}
複製代碼

注意:這邊用的springboot是2.0.x,採起的是直接實現WebMvcConfigurer,由於WebMvcConfigurerAdapter被標識了@Deprecated,就沒有繼承WebMvcConfigurerAdapter了bash

/** @deprecated */
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
    public WebMvcConfigurerAdapter() {
    }
}
複製代碼

第五步:仍是啓動以前的controllermvc

@RestController
@RequestMapping("/api/test")
@Slf4j
public class TestController {

    @RequestMapping(value = "/hello")
    public String test() {
        log.info("test hello.............");
        return "SUCCESS";
    }
複製代碼

看到打印結果以下app

2019-04-27/12:01:04.603||||||||^_^|[http-nio-8088-exec-1] INFO  com.stone.zplxjj.filter.TestFilter 22 - TestFilter filter。。。。。。。。
2019-04-27/12:01:04.612||||||||^_^|[http-nio-8088-exec-1] INFO  com.stone.zplxjj.interceptor.TestInterceptor 26 - TestInterceptor preHandle....
2019-04-27/12:01:04.634||||||||^_^|[http-nio-8088-exec-1] INFO  com.stone.zplxjj.interceptor.TestInterceptor 32 - TestInterceptor postHandle....
2019-04-27/12:01:04.634||||||||^_^|[http-nio-8088-exec-1] INFO  com.stone.zplxjj.interceptor.TestInterceptor 37 - TestInterceptor afterCompletion....
複製代碼

小結

過濾器的實現基於回調函數。而攔截器(代理模式)的實現基於反射,代理又分靜態代理和動態代理,動態代理是攔截器的簡單實現。那什麼時候使用攔截器?什麼時候使用過濾器?框架

  • 若是是非spring項目,那麼攔截器不能用,只能使用過濾器,這裏說的攔截器是基於spring的攔截器。
  • 若是是處理controller先後,既可使用攔截器也可使用過濾器,若是都使用了,注意先後順序。
  • 若是是處理dispaterServlet先後,只能使用過濾器。

更多文章可關注公衆號:stonezplxjj和我的博客:www.zplxjj.comide

相關文章
相關標籤/搜索