MDC跨线程传递上下文

428 阅读1分钟

思路:对任务进行包装,跨线程前将当前上下文取出,在任务中设置MDC上下文。

实现:

public class MDCUtils {
    public static Runnable getMDCTask(Runnable task){
        final Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap();
        return () -> {
            if(Objects.nonNull(copyOfContextMap)){
                MDC.setContextMap(copyOfContextMap);
            }
            try{
                task.run();
            }finally {
                MDC.clear();
            }
        };
    }
}

测试:

@Test
public void test(){
    MDC.put("trace_id", UUID.randomUUID().toString());
    ExecutorService executorService = Executors.newFixedThreadPool(3);
    Runnable print = () -> log.info("trace_id: " + MDC.get("trace_id"));
    executorService.submit(print);
    executorService.submit(MDCUtils.getMDCTask(print));
}

输出结果:

22:37:45.296 [pool-1-thread-1] INFO com.example.aspect.MDCTests - trace_id: null
22:37:45.296 [pool-1-thread-2] INFO com.example.aspect.MDCTests - trace_id: e88e7e20-9d84-4cf2-b3b7-8aa6c873f646