java - 无法覆盖或禁用 spring boot 实例化的 Filter,导致过滤器链中出现重复条目

标签 java spring spring-boot filter servlet-filters

我有一个组件类:

public class FooFilter implements Filter {
    private FooService fooService; //spring-injected dependency
    @Override public void init(FilterConfig filterConfig) {}
    @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){}
    @Override public void destroy() {}
}

在 springConfigured.xml 中定义:

<context:spring-configured />
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <bean class="com.foo.filter.FooFilter" scope="prototype" autowire="byType"/>

</beans>

过滤器是使用 FilterRegistrationBean 在我们的过滤器链中配置的:

@Configuration
public class FooFilterRegistrationConfig {
    private List<String> URL_PATTERNS = Arrays.asList("foo", "bar");
    @Bean
    public FilterRegistrationBean fooFilter(FooFilter filter) {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(filter);
        registration.setName("FooFilter");
        registration.setUrlPatterns(URL_PATTERNS);
        registration.setOrder(4);
        return registration;
    }

    //and some more
}

使用此设置,我们最终会在过滤器链中得到两个 FooFilter。日志:

//a bunch of filters
2017-10-16 16:34:37,468 [RMI TCP Connection(3)-127.0.0.1] INFO  servlet.FilterRegistrationBean - Mapping filter: 'FooFilter' to urls: [*.jsp, *.do, *.faces, *.action, /mvc/*]
//some more filters
2017-10-16 16:34:37,468 [RMI TCP Connection(3)-127.0.0.1] INFO  servlet.FilterRegistrationBean - Mapping filter: 'com.foo.web.filter.FooFilter#0' to: [/*]

类似问题的其他一些答案建议使用 RegistrationConfig 禁用过滤器。如果我尝试使用 registration.setEnabled(false) 禁用 FilterRegistrationConfig 中的过滤器,我仍然会在最后得到附加过滤器。

2017-10-16 16:22:46,078 [RMI TCP Connection(3)-127.0.0.1] INFO  servlet.FilterRegistrationBean - Filter FooFilter was not registered (disabled)
...
2017-10-16 16:22:46,079 [RMI TCP Connection(3)-127.0.0.1] INFO  servlet.FilterRegistrationBean - Mapping filter: 'com.foo.filter.FooFilter#0' to: [/*]

我尝试完全删除 FilterRegistrationConfig 中对此过滤器的引用,并直接在 FooFilter 类上使用 @Order 注释,但因为我们正在指定这个 bean 在我们的 xml 中并且不使用组件扫描,我似乎无法获得 @WebFilter 注释来正确应用 Url 模式。

任何有关如何从我的过滤器链中删除这个 Spring Boot 创建的 FooFilter#0 的提示将不胜感激!

编辑:

我尝试从 xml 中删除 bean 定义。现在我无法将其注入(inject) FilterRegistrationBean 方法,因为这给了我“找不到 'FooFilter' 类型的 beans”错误。

@Bean
public FilterRegistrationBean fooFilter(FooFilter filter) { //no beans of 'FooFilter' type found
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(filter);
    registration.setName("FooFilter");
    registration.setUrlPatterns(URL_PATTERNS);
    registration.setOrder(4);
    return registration;
}

但是,如果我在这里手动实例化 FooFilter,稍后会遇到问题,因为 FooFilter 包含许多未注入(inject)的 spring 管理的依赖项:

@Bean
public FilterRegistrationBean fooFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new FooFilter()); //works fine here, but Spring does not inject dependencies into this object I created, so null pointers later
    registration.setName("FooFilter");
    registration.setUrlPatterns(URL_PATTERNS);
    registration.setOrder(4);
    return registration;
}

最佳答案

FilterRegistrationBean 创建您的 FooFilter bean,您不必单独创建它,删除 FooFilter 的 bean(以下行)

<bean class="com.foo.filter.FooFilter" scope="prototype" autowire="byType"/>

注意: 当 spring 容器创建 bean FilterRegistrationBean 时,它还会创建一个 bean FooFilter,正如您所提到的。
注册.setName("FooFilter");//FooFilter 是 bean 的名称

关于java - 无法覆盖或禁用 spring boot 实例化的 Filter,导致过滤器链中出现重复条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46779572/

相关文章:

java - HashMap 对于 containsValue() 总是返回 false,

java - 应用程序上下文加载很久以前在项目中删除的 Bean

spring-boot - 为什么从 Spring Framework 5.x 中退出对 Jasper 的支持?

java - HTTP 请求等待任务完成

java - Spring Boot Data Rest不支持响应式?

java - 将 Big Derby 嵌入式数据库迁移到 HSQLDB 抛出 java.lang.OutOfMemoryError : Java heap space

java - 如何在请求体中仅发送 id 而不是对象?

java - 在 spring 中通过 resttemplate 发出的每个请求发送客户端证书的正确方法是什么?

java - 如何使用 Spring 注入(inject)网络文件资源?

java - Java和Android之间的图像处理