SpringBoot如何在没有注释的情况下设置Filter的顺序

时间:2016-07-07 10:22:27

标签: spring filter spring-boot annotations

我正在尝试在弹簧过滤器链中插入(在第一个位置)一个简单的自定义Cors过滤器。

如果我这样做

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

它完美无缺 我可以通过在Spring的ServletHandler.java中放置一个断点来验证它,其中有

chain=getFilterChain(baseRequest, target, servlet_holder);

我只是想知道我是否希望使用@Componenent and @Order,而是将Filter bean定义为Application上下文。 如何设置过滤器的顺序?

3 个答案:

答案 0 :(得分:5)

参见示例: 在你的ServletInitializer类中:

@Bean
 public FilterRegistrationBean requestLogFilter() {
        final FilterRegistrationBean reg = new FilterRegistrationBean(createRequestLogFilter());
        reg.addUrlPatterns("/*");
        reg.setOrder(1); //defines filter execution order
        return reg;
 }

 @Bean
 public RequestLogFilter createRequestLogFilter(){
        return new RequestLogFilter();
 }

我的过滤器名称是“requestLogFilter”

警告:不要在类Filter上使用@Component注释。

答案 1 :(得分:3)

在corsFilter的情况下,通常需要在springSecurityFilterChain和其他过滤器(例如springbootFilter)从spring boot开始在链的最开始处设置要加载此过滤器的顺序。否则将破坏CORS支持并且不会引入所需的标题。这可以通过以下方式实现:

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain1.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Integer.MIN_VALUE);
        return bean;
    }
}

bean.setOrder(Integer.MIN_VALUE)将确保它是第一个加载的过滤器。即使有其他过滤器,例如errorPage过滤器,其顺序设置为Integer.MIN_VALUE(-2147483648)。

答案 2 :(得分:0)

另一种选择是让过滤器实现org.springframework.core.Ordered,如果您使用的是spring webflux(它没有FilterRegistrationBean),这是唯一的选择:

public class CorsFilter implements Filter, Ordered {
    //...

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE
    }
}

或者您甚至可以在过滤器中将其设置为变量。