Backend Development 8 min read

Understanding SpringBoot Interceptors: Filters, HandlerInterceptor, AOP, RestTemplate, Feign, and WebFilter

This article introduces the six main types of interceptors in SpringBoot—Filter, HandlerInterceptor, AOP, RestTemplate, Feign, and WebFilter—explaining their typical use‑cases, implementation details, common pitfalls, and best‑practice ordering to help developers choose the right tool for each scenario.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Understanding SpringBoot Interceptors: Filters, HandlerInterceptor, AOP, RestTemplate, Feign, and WebFilter

Introduction

Many developers blindly use HandlerInterceptor for every interception need and end up with complex, hard‑to‑maintain code. This guide presents six "chairs" (interceptor types) in SpringBoot, using a Liangshan (Water Margin) analogy to make the concepts easier to grasp.

First Chair: Filter

Filters act as the "overall camp master" in the analogy, suitable for global concerns such as authentication and request‑time measurement.

@WebFilter("/*")
public class CostFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        long start = System.currentTimeMillis();
        chain.doFilter(req, res); // release the request
        System.out.println("Interface cost:" + (System.currentTimeMillis() - start) + "ms");
    }
}

Filters operate at the servlet container level; obtaining Spring beans inside a filter requires WebApplicationContextUtils .

Second Chair: HandlerInterceptor

HandlerInterceptor is the "second‑in‑command" and is ideal for request‑level permission checks or automatic parameter binding.

public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("X-Token");
        if (!"vip666".equals(token)) {
            response.setStatus(403);
            return false; // block the request
        }
        return true;
    }
}

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/login");
    }
}

Common pitfalls include modifying the response after it has been committed, forgetting to exclude static resources, and mis‑ordering multiple interceptors (lower order value executes earlier).

Third Chair: AOP Interceptor

AOP serves as the "strategist" and is best for method‑level concerns such as caching or transaction management.

@Aspect
@Component
public class CacheAspect {
    @Around("@annotation(com.example.anno.Cacheable)")
    public Object aroundCache(ProceedingJoinPoint jp) throws Throwable {
        String cacheKey = buildKey(jp);
        Object cacheVal = redisTemplate.opsForValue().get(cacheKey);
        if (cacheVal != null) return cacheVal;
        Object result = jp.proceed();
        redisTemplate.opsForValue().set(cacheKey, result, 5, TimeUnit.MINUTES);
        return result;
    }
}

Only Spring‑managed beans can be proxied; the order of AOP aspects should be higher than the transaction aspect, and custom annotations must be placed on interfaces (or use @within for implementations).

Fourth Chair: RestTemplate Interceptor

RestTemplate acts as the "naval commander" for outbound HTTP calls, useful for adding common headers or encrypting request parameters.

public class TraceInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {
        request.getHeaders().add("X-TraceId", UUID.randomUUID().toString());
        return execution.execute(request, body);
    }
}

@Bean
public RestTemplate restTemplate() {
    RestTemplate rt = new RestTemplate();
    rt.getInterceptors().add(new TraceInterceptor());
    return rt;
}

Be aware of body encoding (convert strings to byte arrays) and the execution order of multiple interceptors (the first added runs last). HTTPS calls need additional SSL configuration.

Fifth Chair: Feign Interceptor

Feign works as the "diplomatic envoy" for declarative HTTP clients, allowing uniform signature calculation or header propagation.

public class FeignAuthInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("Authorization", "Bearer " + SecurityContext.getToken());
    }
}

@Configuration
public class FeignConfig {
    @Bean
    public FeignAuthInterceptor feignAuthInterceptor() {
        return new FeignAuthInterceptor();
    }
}

Typical issues include missing request bodies for GET, manual encoding of form parameters (use feign-form ), and handling dynamic path variables with @Param .

Sixth Chair: WebFilter

WebFilter is the "special forces" in a reactive WebFlux environment, often used for CORS handling or unified response encoding.

@Component
public class CorsWebFilter implements WebFilter {
    @Override
    public Mono
filter(ServerWebExchange exchange, WebFilterChain chain) {
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        return chain.filter(exchange);
    }
}

It only works in WebFlux (not traditional MVC) and follows the reactive programming model with non‑blocking pipelines.

Ranking of Interceptor Types

Complexity and performance impact (from low to high): Filter → HandlerInterceptor → AOP → RestTemplate → Feign → WebFilter (reactive full‑chain).

Practical Tips

Order matters: earlier interception saves effort, but avoid business logic in Filters.

Choose the right tool: simple auth → HandlerInterceptor; method‑level control → AOP; micro‑service calls → Feign.

Monitor performance with Arthas to avoid excessive interception latency.

Conclusion

Interception is an art; use the right “weapon” lest you cut yourself.

JavaAOPbackend developmentfeignInterceptorSpringBootFilter
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.