spring boot @Async异步注解上下文透传

文章介绍了在使用Spring Boot的@Async注解时如何处理上下文信息的传递。提供了两种方案,一种是继承线程池并重写相关方法,另一种是通过实现TaskDecorator接口来透传上下文。作者推荐使用方案二,因为它更优雅。
摘要由CSDN通过智能技术生成

之前使用了@Async注解,子线程无法获取到上下文信息,导致流量无法打到灰度,然后改成 线程池的方式,每次调用异步调用的时候都手动透传 上下文(硬编码)解决了问题。

后面查阅了资料,找到了方案不用每次硬编码,来上下文透传数据了。

方案一:
继承线程池,重写相应的方法,透传上下文。
方案二:(推荐)
线程池ThreadPoolTaskExecutor,有一个TaskDecorator装饰器,实现这个接口,透传上下文。

方案一:继承线程池,重写相应的方法,透传上下文。

1、ThreadPoolTaskExecutor spring封装的线程池

ThreadPoolTaskExecutor 线程池代码如下:

https://www.jianshu.com/p/2a58e1df2bbb

    @Bean(ExecutorConstant.simpleExecutor_3)
    public Executor asyncExecutor3() {
        MyThreadPoolTaskExecutor taskExecutor = new MyThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(corePoolSize);
        taskExecutor.setMaxPoolSize(maxPoolSize);
        taskExecutor.setQueueCapacity(queueCapacity);
        taskExecutor.setThreadNamePrefix(threadNamePrefix_3);
        taskExecutor.initialize();
        return taskExecutor;
    }

    //------- 继承父类 重写对应的方法 start
    class MyCallable<T> implements Callable<T> {
        private Callable<T> task;
        private RequestAttributes context;

        public MyCallable(Callable<T> task, RequestAttributes context) {
            this.task = task;
            this.context = context;
        }

        @Override
        public T call() throws Exception {
            if (context != null) {
                RequestContextHolder.setRequestAttributes(context);
            }

            try {
                return task.call();
            } finally {
                RequestContextHolder.resetRequestAttributes();
            }
        }
    }
    class MyThreadPoolTaskExecutor extends ThreadPoolTaskExecutor{

        @Override
        public <T> Future<T> submit(Callable<T> task) {
            return super.submit(new MyCallable(task, RequestContextHolder.currentRequestAttributes()));
        }

        @Override
        public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
            return super.submitListenable(new MyCallable(task, RequestContextHolder.currentRequestAttributes()));
        }
    }
    //------- 继承父类 重写对应的方法 end

1、MyCallable是继承Callable,创建MyCallable对象的时候已经把Attributes对象赋值给属性context了(创建MyCallable对象的时候因为实在当前主线程创建的,所以是能获取到请求的Attributes),在执行call方法前,先执行了RequestContextHol

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值