基于alibabade TTL实现
import com.alibaba.ttl.TransmittableThreadLocal;
import com.dmyz.hc.sign.common.utils.TraceIdUtils;
import com.google.inject.internal.util.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* MVC 自定义拦截器<br/>
*
* @author wangy
* @date 2024-06-24 14:00
*/
public class HttpHandlerInterceptor implements HandlerInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpHandlerInterceptor.class);
/**
* 实现 TransmittableThreadLocal 的 initialValue,beforeExecute,afterExecute接口
*/
static TransmittableThreadLocal<Map<String, String>> ttlMDC = new TransmittableThreadLocal<Map<String, String>>() {
/**
* 在多线程数据传递的时候,将数据复制一份给MDC
*/
@Override
protected void beforeExecute() {
final Map<String, String> mdc = get();
mdc.forEach(MDC::put);
}
@Override
protected void afterExecute() {
MDC.clear();
}
@Override
protected Map<String, String> initialValue() {
return Maps.newHashMap();
}
};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(attributes, true);
String traceId = TraceIdUtils.getTraceId(request);
MDC.put("tid", traceId);
ttlMDC.get().put("tid", traceId);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
try {
MDC.remove("tid");
ttlMDC.get().remove("tid");
ttlMDC.remove();
} catch (Exception e) {
LOGGER.error("MDC remove id error", e);
}
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}