看了很多篇文章的处理方法和在自己亲测的情况下做出说明:
第一种:
这种方式只支持在主线程情况下,能够处理,在多线程情况下,一旦主线程结束,这里还是会为空
第二种
//请求属性可继承,线程共享
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(),true);
这种经测试后发现,主线程直接启动子线程,且执行完自己逻辑后便结束不需理会子线程结果的,请求偶尔成功, 偶尔失败;
也就是,当父线程比子线程执行完慢时,请求属性还在,子线程请求成功;当快时,请求属性随着父线程结束而销毁,子线程的请求属性变为null,请求失败。
第三种
采用的处理方式为:ThreadLocal
新建一个ThreadLocal 工具类,在多线程请求前,获取到需要的属性值或者设置所有的属性值放入工具类MAP种进行存储,在子线程调用服务时通过监听处将需要的值取出,就可以解决了。实际如下:
public class ThreadLocalUtil {
//使用InheritableThreadLocal,使得共享变量可被子线程继承
private static final InheritableThreadLocal<Map<String,String>> headerMap = new InheritableThreadLocal<Map<String, String>>(){
@Override
protected Map<String, String> initialValue() {
return new HashMap<>();
}
};
public static Map<String,String> get(){
return headerMap.get();
}
public static String get(String key) {
return headerMap.get().get(key);
}
public static void set(String key, String value){
headerMap.get().put(key,value);
}
}
在线程执行前加:
(1
Enumeration<String> headerNames = servletRequest.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
if (Objects.equals(name,"feignheader")){
ThreadLocalUtil.set(name,servletRequest.getHeader(name));
}
}
或者直接获取token,在需要的地方再进行赋值。
(2
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes srat = (ServletRequestAttributes) requestAttributes;
HttpServletRequest request = srat.getRequest();
ThreadLocalUtil.set("token", request.getHeader("authorization"));
修改监听处获取请求头信息赋值
(1
@Slf4j
@Configuration
public class FeignConfig implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// //当主线程的请求执行完毕后,Servlet会被销毁,因此在这里需要做判空
// if (attributes != null) {
// HttpServletRequest request = attributes.getRequest();
//
// Enumeration<String> headerNames = request.getHeaderNames();
//
// while (headerNames.hasMoreElements()) {
// String name = headerNames.nextElement();
// //不能把所有消息头都传递下去,否则会引起其他异常;header的name都是小写
// if (name.equals("feignheader")) {
// requestTemplate.header(name,request.getHeader(name));
// }
// }
// }
//读取设置的header信息,传递到下一个服务
Map<String, String> headerMap = ThreadLocalUtil.get();
for (String key : headerMap.keySet()) {
log.info("--从ThreadLocal获取消息头传递到下一个服务:key-[{}],value-[{}]",key,headerMap.get(key));
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数大数据工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/56c1fd3622baba10cf5d872bac91bfdf.png)
![img](https://img-blog.csdnimg.cn/img_convert/c08d1f20d612c6550294c6ca42fa6942.png)
![img](https://img-blog.csdnimg.cn/img_convert/a0398083c13c45e1b2833a1bf74b1e1a.png)
![img](https://img-blog.csdnimg.cn/img_convert/6659b9b74a519276c4e5f1eeb1747b90.png)
![img](https://img-blog.csdnimg.cn/img_convert/c30134fd114bd2bb3a3d2828503800c8.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上大数据开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)**
![img](https://img-blog.csdnimg.cn/img_convert/9cde5deabe9afe284b332e3002a37934.png)
录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注大数据获取)**
[外链图片转存中...(img-o51XDPSZ-1712861985657)]