gpt4 book ai didi

spring-mvc - 使用 @Async 和 TaskDecorator 记录 MDC

转载 作者:行者123 更新时间:2023-12-03 14:58:12 61 4
gpt4 key购买 nike

使用 Spring MVC,我有以下设置:

  • 用于记录请求的 AbstractRequestLoggingFilter 派生过滤器。
  • 一个 TaskDecorator,用于将 MDC 上下文映射从 Web 请求线程编码到 @Async 线程。

  • 我正在尝试使用 MDC(或 ThreadLocal 对象)为处理请求所涉及的所有组件收集上下文信息。

    我可以从@Async 线程正确检索 MDC 上下文信息。但是,如果@Async 线程要将上下文信息添加到 MDC,我现在如何将 MDC 上下文信息编码到处理响应的线程?

    任务装饰器
    public class MdcTaskDecorator implements TaskDecorator {
    @Override
    public Runnable decorate(Runnable runnable) {
    // Web thread context
    // Get the logging MDC context
    Map<String, String> contextMap = MDC.getCopyOfContextMap();

    return () -> {
    try {
    // @Async thread context
    // Restore the web thread MDC context
    if(contextMap != null) {
    MDC.setContextMap(contextMap);
    }
    else {
    MDC.clear();
    }

    // Run the new thread
    runnable.run();
    }
    finally {
    MDC.clear();
    }
    };
    }

    }

    异步方法
    @Async
    public CompletableFuture<String> doSomething_Async() {
    MDC.put("doSomething", "started");
    return doit();
    }

    日志过滤器
    public class ServletLoggingFilter extends AbstractRequestLoggingFilter {
    @Override
    protected void beforeRequest(HttpServletRequest request, String message) {
    MDC.put("webthread", Thread.currentThread().getName()); // Will be webthread-1
    }

    @Override
    protected void afterRequest(HttpServletRequest request, String message) {
    MDC.put("responsethread", Thread.currentThread().getName()); // Will be webthread-2
    String s = MDC.get("doSomething"); // Will be null

    // logthis();
    }

    }

    最佳答案

    我希望你已经解决了这个问题,但如果你没有解决,这里有一个解决方案。
    您所要做的一切都可以概括为以下两个简单的步骤:

  • 继续上课 MdcTaskDecorator .
  • 扩展 AsyncConfigurerSupport用于您的主类并覆盖 getAsyncExecutor()用您定制的装饰器设置装饰器。

  •     public class AsyncTaskdecoratorApplication extends AsyncConfigurerSupport {
    @Override
    public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setTaskDecorator(new MdcTaskDecorator());
    executor.initialize();
    return executor;
    }

    public static void main(String[] args) {
    SpringApplication.run(AsyncTaskdecoratorApplication.class, args);
    }
    }

    关于spring-mvc - 使用 @Async 和 TaskDecorator 记录 MDC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45890181/

    61 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com