Spring - Filter三种定义方式

2021-12-03 09:53:18 浏览数 (1)

Spring Web项目都需要用到Filter来实现各种不同的能力,比如鉴权,限流,日志等。 而且有的Filter实现还需要注入Spring其他bean,这样就需要一些特殊的实现

AccessFilter

简单地打印请求url

代码语言:javascript复制
public class AccessFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        log.info("AccessFilter:doFilter - {}", ((HttpServletRequest)servletRequest).getRequestURI());
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

1. Spring bean

比如使用@Component注解

代码语言:javascript复制
@Component
public class AccessFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        log.info("AccessFilter:doFilter - {}", ((HttpServletRequest)servletRequest).getRequestURI());
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

Servlet扫描

使用注解@ServletComponentScan@WebFilter,实际上就是生成一个类型是FilterRegistrationBean,名字是accessFilter的bean并作为Filter生效.

代码语言:javascript复制
@WebFilter
public class AccessFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        log.info("AccessFilter:doFilter - {}", ((HttpServletRequest)servletRequest).getRequestURI());
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  • SpringSimpleWebApplication
代码语言:javascript复制
@ServletComponentScan
@SpringBootApplication
public class SpringSimpleWebApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringSimpleWebApplication.class, args);
    }
}

手工注册: FilterRegistrationBean

会生成一个类型是FilterRegistrationBean,名字是accessFilterRegister的bean并作为Filter生效.

代码语言:javascript复制
@Bean
public FilterRegistrationBean<AccessFilter> accessFilterRegister(AccessFilter accessFilter) {
    FilterRegistrationBean<AccessFilter> registration = new FilterRegistrationBean<>();
    registration.setFilter(accessFilter);
    registration.addUrlPatterns(filterUrl);
    registration.setName("accessFilter");
    registration.setOrder(1);
    return registration;
}

实践

  • 如果urlPatterns需要从配置文件加载: 那么选择FilterRegistrationBean
  • 如果既要动态加载urlPatterns,还要依赖spring其他的bean: 那么生成bean的同时,再使用FilterRegistrationBean
代码语言:javascript复制
@Slf4j
@Configuration
public class WebConfiguration {
    @Value("${urlPattens:/}")
    private String urlPatterns;
    
    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }

    @Bean
    public FilterRegistrationBean<AccessFilter> accessFilterRegister(AccessFilter accessFilter) {
        FilterRegistrationBean<AccessFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(accessFilter);
        registration.addUrlPatterns(urlPatterns);
        registration.setOrder(1);
        return registration;
    }
}
  • 同名的filter只会有一个生效

0 人点赞