为什么Servlet Filter可以是Spring Bean?

Why Servlet Filter can be Spring Bean?

我对过滤器和拦截器的了解是,作为 J2EE 规范的过滤器是网络服务器的一部分,而不是 Spring 框架。所以一些较早的文章解释说,不可能将过滤器注册为 Spring Bean,而拦截器是可能的。 但是我今天测试得到的结果是 Filters 可以是 Spring Bean 并且在 Filters 上注入 Spring Bean 也可以像 Interceptors 一样。 (我在 SpringBoot Framework 上测试过)

@Component
public class CustomFilterTest implements Filter {

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws ServletException, IOException {
        chain.doFilter(request, response);
    }

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

}
@RestController
@RequiredArgsConstructor
public class ProductController {

    private final CustomFilterTest customFilterTest;

    @GetMapping("/test")
    public ResponseEntity<Void> temp() {
        System.out.println(customFilterTest);
        return ResponseEntity.noContent().build();
    }
}

谁能给我解释一下?

我们必须在这里区分常规 Spring 应用程序和 Spring 启动应用程序。与两者一样,您可以将 servlet 过滤器注册为 bean,但机制有点不同。

Spring 框架

在普通的 Spring 中使用 DelegatingFilterProxy 来实现这一点。 DelegatingFilterProxy 的任务是在根应用程序上下文(ApplicationContext 通过 ContextLoaderListener 注册)中寻找与过滤器同名的 bean。此 bean 必须是您的托管 servlet 过滤器。

@Configuration
@EnableWebMvc
public class WebConfiguration {

  @Bean
  public void YourFilter myFilter() { ... }
}

然后对于 Web 应用程序,您将注册一个名为 myFilterDelegatingFilterProxy 以使其工作。

public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

public void onStartup(ServletContext servletContext)
               throws ServletException {
   super.onStartup(servletContext);
   servletContext.addFilter("myFilter", DelegatingFilterProxy.class);
}

Spring 开机

在 Spring Boot 中有点不同,因为 Spring Boot 也控制着你的 servlet 容器,就像 Tomcat。它基本上意味着 Tomcat 也是您的 ApplicationContext 中的托管 bean,并且 Spring Boot 可以将依赖项注入其中。因此,当 Spring Boot 检测到 servlet 过滤器的 bean 时,它会自动将其添加到过滤器链中(不需要 DelegatingFilterProxy)。

这意味着您的过滤器只需要 @Bean

@Configuration
public class WebConfiguration {

  @Bean
  public YourFilter myFilter() { ... }
}

此外,您可以通过为此过滤器添加额外的 FilterRegistrationBean 来配置 URL 等内容。

结论

对于普通 Spring,DelegatingFilterProxy 自 2005 年发布的 Spring 1.2 以来就已经存在。这意味着如果您正在阅读非常非常非常旧的文章(2005 年之前) ) 这是真的,但是随着 DelegatingFilterProxy 的加入,这不再是了。随着 Spring Boot 的发布,这成为一个更小的问题,它或多或少是注册过滤器(作为托管 bean)的唯一方法。