tips:看了很多帖子,搜索就会有很多帖子分析了原因。简单说来就是通过多线程调用Feign接口时, 由于子线程和主线程之间是线程隔离的,子线程无法自动获取主线程request中的参数, 比如request的header中的“token”字段。详情请自行搜索,只处理方法进行记录。
解决方法
处理方法也比较简单, 首先将主线程的request共享给子线程, 然后在将request中header的参数设置给子线程的request
1.将主线程的request共享给子线程
在启动子线程之前设置
使用这个方法
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
// 在启动子线程之前设置
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
// 标段
CompletableFuture<Map<Long, String>> mapCompletableFuture = CompletableFuture.supplyAsync(
// 这里设置是没有任何意义的
//RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true)
() -> queryxxx(id) // feign接口
);
2.将request中header的参数设置给子线程的request
使用拦截器
@Configuration
public class FeignConfig {
@Bean("requestInterceptor")
public RequestInterceptor requestInterceptor(){
return requestTemplate -> {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (ObjectUtil.isNotNull(requestAttributes)) {
HttpServletRequest request = requestAttributes.getRequest();
String authorization = request.getHeader("Authorization");
requestTemplate.header("Authorization", authorization);
}
};
}
}