java - 如何在 Spring Boot Tomcat 场景中清除线程上下文?
问题描述
我们实现了HandlerInterceptor
在方法内部设置 MDC 线程上下文数据preHandle
。
然后我们将这些数据用于日志记录和度量目的。
MDC.clear()
但是,如果我们在方法内部清除 MDC 数据afterCompletion
,那么对于之后的度量处理程序来说,有价值的信息就会丢失。我说的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
s 都在 Servlet 上下文中,因此它们无法突破。
所以解决方案是使用Filter
带有 order的 servlet Ordered.HIGHEST_PRECEDENCE
。
@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();
}
}
推荐阅读
- ios - 如何在 Swift 中更改滑动操作的 UITableviewCell 背景颜色?
- css - dropdrop、shinyWidgets 中的背景颜色
- grails - 从 urlmapping 跟踪 $controller、$action、$id
- python - 让 Pycharm 在子目录中查看包,而不将其添加为源根目录
- xml - xml 文件加载显示 json 错误
- php - Codeigniter 在 Mac 上使用不同的 MYSQL
- python - 如何从允许重复的python列表中获取所有可能的组合
- docker - Docker AddSigningCredential BIO_new_file:没有这样的文件
- regex - 使用 sed 命令将一个数字替换为另一个数字的正则表达式失败
- php - 如何在 wordpress 中使用 function_exists() 或 class_exists() 而不是 is_plugin_active()