前言
在使用框架日常开发中需要在controller中进行一些异步操作减少请求时间,但是发现在使用@Anysc注解后会出现Request对象无法获取的情况,本文就此情况给出完整的解决方案
原因分析
- @Anysc注解会开启一个新的线程,主线程的Request和子线程是不共享的,所以获取为null
- 在使用springboot的自定带的线程共享后,代码如下,Request不为null,但是偶发的其中body/head/urlparam内容出现获取不到的情况,是因为异步任务在未执行完毕的情况下,主线程已经返回,拷贝共享的Request对象数据被清空
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//设置子线程共享
RequestContextHolder.setRequestAttributes(servletRequestAttributes, true);
HttpServletRequest request = servletRequestAttributes.getRequest();
解决方案
前置条件
- 启动类添加@EnableAsync注解
- 标记@Async的异步方法不能和调用者在同一个class中
pom配置
<!-- 阿里线程共享 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.11.0</version>
</dependency>
requrest共享
通过TransmittableThreadLocal对象进行线程对象共享
public class CommonUtil {
public static TransmittableThreadLocal<HttpServletRequest> requestTransmittableThreadLocal = new TransmittableThreadLocal<HttpServletRequ