日志框架 - 基于spring-boot - 实现5 - 线程切换

日志框架系列讲解文章
日志框架 - 基于spring-boot - 使用入门
日志框架 - 基于spring-boot - 设计
日志框架 - 基于spring-boot - 实现1 - 配置文件
日志框架 - 基于spring-boot - 实现2 - 消息定义及消息日志打印
日志框架 - 基于spring-boot - 实现3 - 关键字与三种消息解析器
日志框架 - 基于spring-boot - 实现4 - HTTP请求拦截
日志框架 - 基于spring-boot - 实现5 - 线程切换
日志框架 - 基于spring-boot - 实现6 - 自动装配

上一篇我们讲了框架实现的第四部分:实现HTTP请求的拦截
本篇主要讲框架实现的第五部分:如何在线程切换时保留上下文信息。

由于 LogbackMDC 实际上是一个 ThreadLocal 的实现(参考这里),因此,当异步执行产生线程切换时,需要将 MDC 保存的信息进行切换。

为了实现此功能,我研究了 Spring 的异步执行组件,发现 Spring 中有一个可用的线程装饰器TaskDecorator。这个是Spring Core 4.3版本才加入的接口,在Spring的文档中没有提及,也没有提供任何实现,但正好是我所需要的功能。代码如下。

/**
 * 解决异步执行时MDC内容延续的问题
 */
public class MDCTaskDecorator implements TaskDecorator {
    
    @Override
    public Runnable decorate(Runnable runnable) {
        return new MDCContinueRunableDecorator(runnable);
    }
    
    /**
     * 执行线程装饰器
     */
    protected class MDCContinueRunableDecorator implements Runnable {
        
        private final Runnable delegate;
        
        protected final Map<String, String> logContextMap;
        
        public MDCContinueRunableDecorator(Runnable runnable) {
            this.delegate = runnable;
            this.logContextMap = MDC.getCopyOfContextMap();
        }
        
        @Override
        public void run() {
            MDC.setContextMap(this.logContextMap);
            this.delegate.run();
            MDC.clear();
        }
    }
}

然后,需要自定义实现一个 TaskExecutor,替换Spring提供的默认实现,代码如下。

    /**
     * 自定义线程池
     * <p>
     * 用于线程切换时的MDC延续
     */
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(maxPoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setTaskDecorator(new MDCTaskDecorator());
        executor.setThreadNamePrefix("MDCAdaptTaskExcutor-");
        executor.initialize();
        return executor;
    }

至此,线程切换时的问题已经解决。只要异步处理使用了自定义的 TaskExecutor ,即可实现上下文的自动传递。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值