Master SpringBoot AOP, Interceptors, and Argument Resolvers with Ready-to-Use Templates

This guide explains how to quickly set up SpringBoot AOP, interceptor, and HandlerMethodArgumentResolver development by providing Maven dependencies, annotation definitions, code templates, usage examples, and the execution order of these components.

Lin is Dream
Lin is Dream
Lin is Dream
Master SpringBoot AOP, Interceptors, and Argument Resolvers with Ready-to-Use Templates

In SpringBoot development, AOP based on dynamic proxies allows you to use annotations to capture method parameters before and after execution, enabling common tasks such as logging, status alerts, and template code injection.

Interceptors (HandlerInterceptor) and parameter resolvers (HandlerMethodArgumentResolver) serve similar purposes, allowing you to obtain method arguments for tasks like parameter assignment, validation, and path interception.

SpringBoot AOP Development Template

1. Import Maven Dependency

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. Define Annotation

package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
    // optional parameters, e.g., log request args, return value, etc.
}

3. Create AOP Aspect

package com.example.demo.aspect;

import com.example.demo.annotation.LogExecutionTime;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

@Component
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class LoggingAspect {
    @Around("@annotation(com.example.demo.annotation.LogExecutionTime)")
    public Object logMethodExecution(JoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object[] args = joinPoint.getArgs();
        System.out.println("Method arguments: ");
        for (Object arg : args) {
            System.out.println(arg);
        }
        Object result = joinPoint.proceed();
        System.out.println("Method result: " + result);
        long elapsedTime = System.currentTimeMillis() - startTime;
        System.out.println("Method execution time: " + elapsedTime + " ms");
        return result;
    }
}

SpringBoot Interceptor Development Template

1. Implement Interceptor

package com.example.demo.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("Request URI: " + request.getRequestURI());
        // assign attributes, validation, etc.
        return true; // continue processing
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           org.springframework.web.context.request.WebRequest webRequest) throws Exception {
        // modify response data if needed
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (ex != null) {
            System.err.println("Exception occurred: " + ex.getMessage());
        }
        // final logging
    }
}

Common Interceptor Use Cases

Log request start and end times in preHandle and postHandle.

Permission validation based on URL or user roles.

Request parameter validation with error responses.

CORS handling in afterCompletion.

SpringBoot Parameter Resolver Development Template

HandlerMethodArgumentResolver is a Spring MVC mechanism for custom method‑parameter parsing. By defining a custom annotation (e.g., @CurrentUser) you can inject the current logged‑in user object into controller methods.

1. Define Custom Annotation

package com.example.demo.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
    // optional attributes, e.g., required = true
}

2. Implement HandlerMethodArgumentResolver

package com.example.demo.resolver;

import com.example.demo.annotation.CurrentUser;
import com.example.demo.model.User;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;

@Component
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(CurrentUser.class) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                org.springframework.web.context.request.NativeWebRequest webRequest,
                                org.springframework.web.bind.support.WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        // Retrieve user from session or security context
        return (User) request.getSession().getAttribute("currentUser");
    }
}

3. Register Resolver and Interceptor

package com.example.demo.config;

import com.example.demo.interceptor.CustomInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Bean
    public CustomInterceptor customInterceptor() {
        return new CustomInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor()).addPathPatterns("/**");
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new CurrentUserMethodArgumentResolver());
    }
}

4. Use Annotation in Controller

package com.example.demo.controller;

import com.example.demo.annotation.CurrentUser;
import com.example.demo.model.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/profile")
    public String getUserProfile(@CurrentUser User user) {
        return "Current user: " + user.getUsername();
    }
}

Execution Order

Request reaches DispatcherServlet.

Interceptor preHandle methods execute (in order).

HandlerMethodArgumentResolver parses method parameters.

AOP @Before advice runs.

Controller method executes.

AOP @Around advice (if present) wraps execution.

AOP @After advice runs.

Interceptor postHandle methods execute.

View rendering.

Interceptor afterCompletion methods execute.

AOPInterceptortutorialArgumentResolver
Lin is Dream
Written by

Lin is Dream

Sharing Java developer knowledge, practical articles, and continuous insights into computer engineering.

0 followers
Reader feedback

How this landed with the community

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.