如果过滤器被声明为Spring bean,有没有办法告诉Spring不要注册过滤器?

时间:2015-09-17 18:31:57

标签: java spring spring-mvc filter

我正在构建一个应用程序框架,它(作为实现的一部分)使用Spring FilterRegistrationBean bean注册过滤器。注册方法(用@Bean注释)根据确定过滤器是打开还是关闭的某些逻辑返回包裹真实过滤器的FilterRegistrationBean或虚拟ServletContextInitializer。 (这样可以避免使用停用的过滤器使过滤器链混乱。)

// This method is in some other class which is an `@Component`, and not within the same class as the `Filter` itself
@Bean
public ServletContextInitializer register() {
    if (someLogic()) {
        Filter filter = new MyRealFilter();
        FilterRegistrationBean frb = new FilterRegistrationBean(filter);
        // ... Stuff to do with configuring the filter patterns etc. ...
        return frb;
    } else {
        return new DummyServletContextInitializer(); // a SCI which does nothing
    }
}

现在,我希望过滤器具有上下文感知能力。所以我将过滤器设置为@Component

@Component
public class MyRealFilter implements Filter {
    @Autowired
    private ApplicationContext applicationContext;

    // stuff
}

如果打开过滤器(上面的someLogic()返回true),这可以正常工作,而Spring仍然尊重您在FilterRegistrationBean上指定的任何配置。但是,如果关闭过滤器,过滤器仍然会被注册,因为它是@Component。似乎Spring会自动注册声明为@Component的任何过滤器,除非该过滤器已在FilterRegistrationBean中注册。

有没有办法告诉Spring不要注册声明为@Component的过滤器?或者任何其他方法来解决这个问题,我希望过滤器能够识别上下文,但仍然只能通过FilterRegistrationBean而不是直接注册?

更新:我后来发现,如果我在@ApplicationContext方法中自己构造bean,实际上register()无法自动装配。解决这个问题的方法是将FilterRegistrationBean的子类声明为@Component @PostConstruct,而不是使用register()

1 个答案:

答案 0 :(得分:1)

使用@ConditionalOn内容确定需要注册的内容。而不是将其放在过滤器或@Bean方法上,而不是@Configuration类。

@Configuration
public class OptionalWebFiltersConfiguration {

    @Configuration
    @ConditionalForFilterX
    public static class FilterXConfiguration {

        @Bean
        public Filter filterX() {
             return new FilterX();
        }

        @Bean
        public FilterRegistrationBean filterXRegistrationBean() {
             FilterRegistrationBean frb = new FilterRegistrationBean frb = new FilterRegistrationBean(filterX());
             // other config
             return verb;
        }
    }
}

这将仅在满足条件时包括过滤器配置,而不包含重复条件指令。这也是Spring Boot注册过滤器,监听器等的方式(例如参见DispatcherServlet is registered)。