MangKyu
MangKyu

Reputation: 51

Why Servlet Filter can be Spring Bean?

What i know about Filter and Interceptor is that Filters as J2EE Specifications are part of the webserver and not the Spring framework. So some older articles explain that it is impossible to register filters as Spring Bean while Interceptor is possible. But the results I got when I tested today is that Filters can be Spring Bean and also inject Spring Bean on Filters are possible too like Interceptors. (I tested on 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();
    }
}

Can anyone please explain to me?

Upvotes: 1

Views: 1266

Answers (1)

M. Deinum
M. Deinum

Reputation: 124526

We have to make a distinction between a regular Spring application and a Spring Boot application here. As with both, you can register a servlet filter as a bean, but the mechanism is a bit different.

Spring Framework

In plain Spring use the DelegatingFilterProxy to achieve this. The task of the DelegatingFilterProxy is to look for a bean with the same name as the filter in the root application context (the ApplicationContext registered through the ContextLoaderListener). This bean has to be your managed servlet filter.

@Configuration
@EnableWebMvc
public class WebConfiguration {

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

Then for the web application you would register a DelegatingFilterProxy with the name myFilter to make this work.

public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

Spring Boot

In Spring Boot it is a bit different as Spring Boot is also in control of your servlet container, like Tomcat. It basically means that Tomcat is also a managed bean in your ApplicationContext and Spring Boot can inject dependencies into it. So when Spring Boot detects a bean for the servlet filter it will automatically add it to the filter chain (without the need of a DelegatingFilterProxy).

Which means only an @Bean for your filter is needed.

@Configuration
public class WebConfiguration {

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

Additionally you can configure things like URLs etc. by adding an additional FilterRegistrationBean for this filter.

Conclusion

For plain Spring the DelegatingFilterProxy has been around since Spring 1.2 which was released in 2005. This means if you are reading really, really, really old articles (before 2005) this was true, however with the addition of the DelegatingFilterProxy, this isn't anymore. With the release of Spring Boot, this became even a lesser issue, is it more or less is the only way to register a filter (as a managed bean).

Upvotes: 8

Related Questions