Spring Boot之拦截器与过滤器

一、拦截器与过滤器
AOP不是一种具体的技术,而是一种编程思想。

对于横向的功能,比如,在所有的service方法中开启事务,或者统一记录日志等功能,面向对象的是无法解决的。所以AOP——面向切面编程其实是面向对象编程思想的一个补充。
过滤器和拦截器都属于面向切面编程的具体实现。

过滤器(Filter)与拦截器()主要区别:
Filter是依赖于Servlet容器,属于Servlet规范的一部分,而拦截器则是独立存在的;

Filter的执行由Servlet容器回调完成,而拦截器通常通过动态代理的方式来执行;

Filter的生命周期由Servlet容器管理,而拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例,使用更方便;

二、过滤器的实现

在Spring boot中,我们需要FilterRegistrationBean来完成配置。其实现过程如下:

package com.test.config;

import com.test.domain.LogCostFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean registration(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new LogCostFilter());//实例化Filter类
        filterRegistrationBean.addUrlPatterns("/*");//设置匹配模式,这里设置为所有,可以按需求设置为"/hello"等等
        filterRegistrationBean.setName("LogCostFilter");//设置过滤器名称
        filterRegistrationBean.setOrder(1);//设置执行顺序
        return filterRegistrationBean;
    }
}

 启动服务器访问任意URL皆可得到打印的时间戳
过滤器的另一种实现方法:可以在启动类上使用 @ServletComponentScan("com.test.domian.FilterCostConfig")和实现了Filter接口的自定义类上使用注解 @WebFilter(urlPatterns = "/*",filterName = "LogCostFilter"),不过@WebFilter这个注解是Servlet3.0的规范,且并没有指定执行的顺序,其执行顺序依赖于Filter的名称,是根据Filter类名(注意不是配置的filter的名字)的字母顺序倒序排列,并且@WebFilter指定的过滤器优先级都高于FilterRegistrationBean配置的过滤器。

三、拦截器的实现
使用拦截器来实现上面同样的功能,记录请求的执行时间。

自定义一个实现HandlerInterceptor 接口的拦截器类:

拦截器类的配置:

package com.test.config;

import com.test.interceptor.LogcostInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
    /**
     * 静态资源配置
     */
    /*@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/img/**")
                .addResourceLocations("classpath:/imgs/");

        super.addResourceHandlers(registry);
    }*/

    /**
     * 默认首页配置
     */
//    @Override
//    public void addViewControllers(ViewControllerRegistry registry) {
//        registry.addViewController("/").setViewName("forward:/index");
//        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
//        super.addViewControllers(registry);
//    }

    /**
     * interceptor配置
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogcostInterceptor())
                //添加需要验证登录用户操作权限的请求
                .addPathPatterns("/**")
                //这里add为“/**”,下面的exclude才起作用,且不管controller层是否有匹配客户端请求,拦截器都起作用拦截
//                .addPathPatterns("/hello")
                //如果add为具体的匹配如“/hello”,下面的exclude不起作用,且controller层不匹配客户端请求时拦截器不起作用

                //排除不需要验证登录用户操作权限的请求
                .excludePathPatterns("/wang")
                .excludePathPatterns("/css/**")
                .excludePathPatterns("/js/**")
                .excludePathPatterns("/images/**");
        //这里可以用registry.addInterceptor添加多个拦截器实例,后面加上匹配模式
        super.addInterceptors(registry);//最后将register往这里塞进去就可以了
    }
}

这里我们重写了addInterceptors这个方法,进行拦截器的配置,主要配置项就两个,一个是指定拦截器(定义方法行为),第二个是指定拦截的URL(模式匹配)。

注释部分的静态资源配置和默认首页配置本人还未做实验,应该没问题的

再启动系统访问任意一个URL即可得到打印的时间戳
现在我们权限和认证更多的是在Spring Boot中整合使用shiro或者Spring Security来完成,比较少用自定义拦截器了,不过可以用拦截器实现其他功能,比如ip黑名单等等特殊场景;

你可能感兴趣的:(Java,spring,boot,拦截器,过滤器)