Spring AOP实现MDC日志埋点后调用内部方法返回时MDC值丢失问题求助
问题成因
- 最常见原因:
ddlDataService.fetchAndSaveData()方法也被操作MDC的AOP切面命中,该切面的finally代码块执行了MDC.clear()全量清空了当前线程的MDC上下文,导致回到processInboundData方法后MDC已经没有journey字段。 - 其他可能:
fetchAndSaveData()内部逻辑主动调用了MDC.clear()清空了MDC上下文。
解决方案
方案1:修改MDC操作逻辑,禁止全量清空MDC
所有操作MDC的逻辑都遵循「谁添加谁清理、仅处理自身负责的键」的原则,不要直接调用MDC.clear(),改为保存当前键的旧值,执行完业务逻辑后仅恢复该键的原有状态:
@Around("execution(*package.processInboundData(..))") public Object processInboundData(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable { // 先保存Journey键的原有值,未设置时为null String oldJourney = MDC.get(Journey); MDC.put(Journey , "Inbound"); try { return proceedingJoinPoint.proceed(); } finally { // 仅恢复Journey键的状态,不影响其他MDC键 if (oldJourney == null) { MDC.remove(Journey); } else { MDC.put(Journey, oldJourney); } } }
该方案同时适配内部方法主动操作MDC、内部方法被MDC切面命中两种场景,通用性最高。
方案2:调整切点表达式避免重复切中内部方法
检查所有MDC相关切面的切点规则,确保仅顶层入口方法(如processInboundData、processOutbound)会被命中,内部调用的业务方法不触发MDC切面逻辑。
方案3:排查内部方法的MDC操作
如果fetchAndSaveData内部存在主动调用MDC.clear()的逻辑,将其修改为仅清理自身添加的MDC键即可。
内容的提问来源于stack exchange,提问作者SMAR
相关产品推荐
相关产品推荐

