Spring Boot一次接口请求涉及的完整执行链路

Spring Boot一次接口请求涉及的完整执行链路


🔁 Spring 项目请求执行链路(简化视图)

text 复制代码
客户端请求(浏览器、Postman)
        ↓
Tomcat(Servlet 容器)
        ↓
【Listener 监听器】
        ↓
【Filter 过滤器】(如安全认证)
        ↓
DispatcherServlet(中央调度器)
        ↓
【HandlerInterceptor 拦截器】
        ↓
【参数解析器(HandlerMethodArgumentResolver)】
        ↓
Controller 方法执行

🧩 各组件详细解析与执行顺序

1️⃣ Listener(Servlet Listener)【最早执行】

  • 监听整个请求生命周期,例如:
    • ServletRequestListener
    • HttpSessionListener
    • ServletContextListener
  • 适合做请求进入/退出日志记录、资源准备等操作

📌【执行时机】:Tomcat 接收到请求,构造 Request 后即触发


2️⃣ Filter(过滤器)【Servlet 级别】

  • 实现 javax.servlet.Filter 接口
  • 是整个请求过程中最早的一环,甚至可以不进入 Spring
  • 常见用途:登录校验、XSS 过滤、CORS 跨域处理等

📌【执行时机】:

  • DispatcherServlet 执行前
  • 可通过 FilterRegistrationBean 控制顺序(@Order@WebFilter

3️⃣ DispatcherServlet(Spring MVC 核心调度器)

  • 核心职责:将请求分发给对应的 Controller
  • 执行顺序如下:
text 复制代码
DispatcherServlet.doDispatch()
  ├─ 处理 Multipart 请求(如文件上传)
  ├─ 调用 HandlerMapping 查找 Controller
  ├─ 调用 HandlerInterceptor.preHandle()
  ├─ 参数解析器(ArgumentResolver)
  ├─ 调用 Controller 方法
  ├─ HandlerInterceptor.postHandle()
  └─ 渲染视图(如 JSON、HTML)

4️⃣ HandlerInterceptor(拦截器)【Spring 层】

  • 实现 HandlerInterceptor 接口
  • 常用于权限校验、日志记录、参数加工等
  • 分为三段生命周期方法:
方法 时机
preHandle Controller 方法
postHandle Controller 方法 ,视图渲染前
afterCompletion 请求全部结束后(包括异常)

📌【执行时机】:由 Spring MVC 控制,必须经过 DispatcherServlet 才会生效


5️⃣ Aspect(AOP 切面)【更精细控制】

  • 使用 @Aspect 实现 AOP,可以控制更细粒度的方法前后逻辑
  • 可用于审计、日志、权限等

📌【执行时机】:真正进入 Controller 方法执行时,环绕通知才会生效

  • 与拦截器的最大区别是,它操作的是方法级别,支持注解切点、参数切点等
  • 可以作用于 Service、Mapper、Controller 等层面

6️⃣ HandlerMethodArgumentResolver(参数解析器)

  • 将 HTTP 参数解析为 Java 方法参数
  • 常见的如 @RequestParam, @PathVariable, @RequestBody 就是由这些解析器完成的

7️⃣ Controller 方法执行

至此,请求真正进入你的业务方法。


🧯 异常处理(ExceptionResolver)

  • 如果 Controller 或任何处理过程中抛出异常,会进入 HandlerExceptionResolver
  • Spring 默认提供:
    • DefaultHandlerExceptionResolver
    • ResponseStatusExceptionResolver
    • ExceptionHandlerExceptionResolver(处理 @ExceptionHandler 注解的方法)

📌 总结执行顺序一览

执行阶段 说明
Listener 请求刚进来,监听请求/会话/上下文
Filter Servlet 层面统一过滤
DispatcherServlet Spring MVC 核心分发器
Interceptor.preHandle 控制器方法执行前,适合权限校验
ArgumentResolver 将参数注入到 Controller 方法中
AOP Around 控制器方法执行前后,可用于埋点日志
Controller 方法 正式执行业务代码
Interceptor.postHandle 方法执行后,视图渲染前
Interceptor.afterCompletion 全流程结束后调用,包括异常情况
ExceptionResolver 统一异常处理

✅ Filter、Interceptor、AOP 区别总览

对比维度 Filter Interceptor(拦截器) AOP(切面)
所属技术 Servlet 规范(JEE 层) Spring MVC Spring AOP(基于代理)
是否依赖 Spring ❌ 无需依赖 Spring ✅ 依赖 Spring MVC ✅ 依赖 Spring(Context + AOP)
拦截对象 所有请求(静态资源也可) Controller 映射方法(Handler) Bean 的方法调用
拦截级别 HTTP 请求级别 MVC 控制器调用前后 方法级别(可拦 Service、DAO、Controller)
是否感知注解 ❌ 无 ✅ 可以读取注解 ✅ 强大注解支持
常见应用 日志打印、CORS、XSS、限流等 登录鉴权、权限控制、日志追踪等 审计日志、事务控制、性能统计、通用逻辑抽取
是否支持链式调用 ✅ FilterChain ✅ 多个拦截器链 ✅ 多个切面 + 顺序控制(@Order)
注册方式 Web.xml 或 Spring Boot 注册 Bean 实现接口 + WebMvcConfigurer 注册 @Aspect 注解 + @EnableAspectJAutoProxy
可用于非 Spring ✅ 是(纯 Servlet 容器可用) ❌ 否(只能在 Spring MVC 项目) ❌ 否(必须由 Spring 管理的 Bean)

📦 Filter 注册方式(Spring Boot)

方式 1:使用 @WebFilter 注解 + @ServletComponentScan

java 复制代码
@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        // 前置处理
        chain.doFilter(request, response); // 放行
        // 后置处理
    }
}

需要在配置类或主启动类上添加:

java 复制代码
@ServletComponentScan

方式 2:使用 Spring Boot 的 FilterRegistrationBean

java 复制代码
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<LogFilter> logFilter() {
        FilterRegistrationBean<LogFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new LogFilter());
        bean.addUrlPatterns("/*");
        bean.setOrder(1); // 控制执行顺序,值越小越先执行
        return bean;
    }
}

🔗 Interceptor 注册方式(Spring Boot)

java 复制代码
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")  // 拦截路径
                .excludePathPatterns("/login"); // 排除路径
    }
}

拦截器实现:

java 复制代码
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 登录校验逻辑
        return true; // true 放行,false 拦截
    }
}

🔍 AOP 使用与示例

AOP 切面适用于方法级别的增强操作,比如审计日志、数据脱敏、方法耗时统计等。

1. 添加依赖(如果是 Spring Boot 默认 Web 项目已经包含)

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 定义切面类

java 复制代码
@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.example.controller..*(..))")
    public void controllerMethods() {}

    @Before("controllerMethods()")
    public void beforeAdvice(JoinPoint joinPoint) {
        // 打印请求信息
    }

    @Around("controllerMethods()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        System.out.println("执行耗时:" + (end - start));
        return result;
    }
}

📌 执行顺序对比总结(默认情况)

text 复制代码
↓ 请求进入 ↓
1. Listener(Servlet 容器级别)
2. Filter(全局过滤,早于 Spring)
3. DispatcherServlet
4. Interceptor.preHandle(Spring 拦截器)
5. AOP @Before / @Around(方法增强)
6. Controller 执行
7. AOP @After / @AfterReturning / @AfterThrowing
8. Interceptor.postHandle
9. Interceptor.afterCompletion

🎯 使用建议

目标 推荐使用
全局过滤如跨域、XSS、编码等 Filter
登录认证、权限控制 Interceptor
方法日志、埋点、性能统计 AOP
文件上传前置处理、敏感词替换等 Filter 或 AOP(配合注解)
接口日志记录、签名校验 Interceptor 或 AOP
相关推荐
chuanauc几秒前
Kubernets K8s 学习
java·学习·kubernetes
一头生产的驴17 分钟前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao23 分钟前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc78727 分钟前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张33 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx6 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野6 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person7 小时前
Java SE--方法的使用
java·开发语言·算法
小阳拱白菜8 小时前
java异常学习
java