网站分站原理,wordpress 手机端页面,羽毛球赛事安排,注册域名之后如何做网站一步一步讲清楚#xff1a;
#x1f449; 接口耗时为什么不能写在 Controller 里#xff1f;
#x1f449; 在拦截器里应该怎么“正确、优雅地处理”#xff1f;一、为什么不在 Controller 里写耗时代码#xff1f;示例代码是这样的#xff1a;long start System.curre…一步一步讲清楚接口耗时为什么不能写在 Controller 里在拦截器里应该怎么“正确、优雅地处理”一、为什么不在 Controller 里写耗时代码示例代码是这样的long start System.currentTimeMillis(); // 业务逻辑 long cost System.currentTimeMillis() - start; log.info(接口耗时: {} ms, cost);❌ 问题有 4 个大量重复代码每个接口都要写一遍业务代码被日志污染容易漏写 / 写错无法统一统计所有接口这是典型的横切关注点Cross-Cutting Concern 非常适合用拦截器 / AOP二、正确方案在拦截器中统一记录接口耗时Spring MVC 中拦截器HandlerInterceptor是最合适的位置。三、拦截器记录耗时的核心思路preHandle → 记录开始时间 controller → 业务逻辑 afterCompletion → 计算耗时 打日志四、标准实现方式推荐写法1️⃣ 在 preHandle 中记录开始时间Component public class TimeCostInterceptor implements HandlerInterceptor { private static final Logger log LoggerFactory.getLogger(TimeCostInterceptor.class); private static final String START_TIME startTime; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { request.setAttribute(START_TIME, System.currentTimeMillis()); return true; }2️⃣ 在 afterCompletion 中计算耗时Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { Long startTime (Long) request.getAttribute(START_TIME); if (startTime null) { return; } long cost System.currentTimeMillis() - startTime; log.info(接口耗时 | {} {} | {} ms, request.getMethod(), request.getRequestURI(), cost); } }3️⃣ 注册拦截器Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TimeCostInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/static/**); } }五、最终日志效果真实可用2025-01-01 10:00:01.456 INFO [traceId9f8a3b7c2d1a4e] 接口耗时 | GET /users/1 | 38 ms✔ 不侵入 Controller✔ 所有接口自动统计✔ 日志格式统一六、和 TraceId链路追踪如何配合如果你已经使用了MDC TraceId前一篇博客内容MDC.put(traceId, traceId);那么这里的耗时日志会自动带上 TraceId无需额外处理。 这就是为什么TraceFilterTimeCostInterceptor要一起使用七、进阶优化生产环境强烈推荐1️⃣ 慢接口告警非常实用if (cost 1000) { log.warn(慢接口 | {} {} | {} ms, request.getMethod(), request.getRequestURI(), cost); }2️⃣ 区分正常 / 异常请求if (ex ! null) { log.error(接口异常 | {} {} | {} ms, request.getMethod(), request.getRequestURI(), cost, ex); }3️⃣ 只统计 Controller 方法if (!(handler instanceof HandlerMethod)) { return; }避免静态资源、错误页面干扰统计。八、拦截器 vs AOP该选哪个场景推荐统计接口耗时✅ 拦截器记录方法级别日志AOP参数 / 返回值埋点AOP接口级统一日志✅ 拦截器HTTP 接口维度 拦截器最合适九、一句话总结面试 / 实战都能用接口耗时属于横切关注点应统一在 Spring MVC 拦截器中处理避免侵入 Controller 业务逻辑。