29. Advanced Filter Registration & OncePerRequestFilter

FilterRegistrationBean & URL Scoping

Master FilterRegistrationBean, explicit URL mapping, preventing duplicate filter registration bugs, and URL scoping strategies.

FilterRegistrationBean & URL Scoping

While declaring a filter as a @Component automatically registers it for all URL paths (/*), production applications often require explicit URL scoping (e.g. applying filters strictly to /api/* endpoints).


1. Filter Registration Strategies

Approach A: Automatic Component Discovery (@Component)

  • Usage: Annotate filter class with @Component.
  • Behavior: Automatically registered by Spring Boot for all incoming paths (/*). Order defined via @Order.
  • Limitation: Cannot configure URL pattern exclusions or custom dispatcher types.

Do NOT annotate the filter class with @Component. Instead, declare a @Bean returning a FilterRegistrationBean:

@Configuration
public class CustomFilterConfig {

    @Bean
    public FilterRegistrationBean<ApiLoggingFilter> apiLoggingFilterRegistration() {
        FilterRegistrationBean<ApiLoggingFilter> registrationBean = new FilterRegistrationBean<>();

        // 1. Set Filter Instance
        registrationBean.setFilter(new ApiLoggingFilter());

        // 2. Define Explicit URL Scoping Patterns
        registrationBean.addUrlPatterns("/api/v1/*", "/api/v2/*");

        // 3. Define Explicit Order
        registrationBean.setOrder(1);

        // 4. Set Filter Registration Name
        registrationBean.setName("apiLoggingFilter");

        // 5. Configure Specific Dispatcher Types
        registrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);

        return registrationBean;
    }
}

2. The Duplicate Registration Trap!

Duplicate Execution Bug: Annotating a Filter class with @Component AND creating a FilterRegistrationBean for that same filter class causes Spring Boot to register the filter TWICE! The filter will execute twice on every request, producing duplicate logs or double-processing errors!

// BAD: Class has @Component...
@Component 
public class AuditFilter implements Filter { ... }

// AND Configuration declares FilterRegistrationBean with new AuditFilter()...
@Bean
public FilterRegistrationBean<AuditFilter> auditFilterRegistration() {
    // AuditFilter EXECUTES TWICE ON EVERY REQUEST!
}

Fix

Remove @Component from the filter class when registering it via FilterRegistrationBean!


3. URL Scoping Comparison

Scoping MechanismConfiguration LocationExecution OverheadBest Suited For
FilterRegistrationBean.addUrlPatterns()@Configuration ClassLowest (Web container skips filter entirely for unmatched paths)Broad, static path patterns (/api/*)
Manual getRequestURI() CheckInside doFilter()Medium (Filter invoked, but short-circuits)Dynamic, runtime URI checks
OncePerRequestFilter.shouldNotFilter()Inside Filter ClassLow (Spring hook skips doFilterInternal())Complex programmatic exclusions

❓ Knowledge Check

Knowledge Check

What happens if a developer annotates a Filter with @Component AND creates a FilterRegistrationBean for it in a @Configuration class?

Knowledge Check

What is the advantage of using FilterRegistrationBean.addUrlPatterns('/api/*') over a manual path check inside doFilter()?

On this page