思路:对任务进行包装,跨线程前将当前上下文取出,在任务中设置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