我们实现了一个HandlerInterceptor
来在preHandle
方法中设置MDC线程上下文数据。
然后我们将这些数据用于日志记录和指标目的。
但是,如果我们在 afterCompletion
方法中使用 MDC.clear()
清除 MDC 数据,则此后的指标处理程序会丢失有值(value)的信息。我特别谈论的是 WebMvcTagsProvider
,但我认为这适用于所有类型的用例。
既然有线程池,线程最终会被重用,并且包含之前HTTP请求的MDC上下文,这是非常糟糕的!
那么如何在 setup 和 Finalize 方法中“包装”线程的使用呢? 理想情况下,这将是一个通用解决方案。我不想更改现有代码。目标是新传入请求无法访问之前的 MDC 上下文。
我已经知道如何在 Java EE 世界中解决这个问题,例如:
@Provider
@Priority(Priorities.USER + 1)
public class MdcClearFilter implements ContainerResponseFilter {
@Override
public void filter(
ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
MDC.clear();
}
}
那么我该如何在 Spring Boot 世界中做同样的事情呢?
最佳答案
由于 HandlerInterceptor
都位于 Servlet 上下文中,因此它们无法突破。
因此,解决方案是使用顺序为 Ordered.HIGHEST_PRECEDENCE
的 servlet Filter
。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MDCClearFilter implements Filter {
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
MDC.clear();
}
}
关于java - Spring boot Tomcat场景下如何清除线程上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58978540/