当前位置:   article > 正文

spring boot开启异步导致RequestContextHolder.currentRequestAttributes()为NULL_requestcontextholder.currentrequestattributes() 获取

requestcontextholder.currentrequestattributes() 获取为空

现象

@Slf4j
public class MartinOAuth2FeignRequestInterceptor implements RequestInterceptor {
	。。。
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
	。。。
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在使用feign的RequestInterceptor 在服务间传递参数时,RequestContextHolder.currentRequestAttributes()报空指针异常

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
	at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
	at com.java2e.martin.common.security.interceptor.MartinOAuth2FeignRequestInterceptor.apply(MartinOAuth2FeignRequestInterceptor.java:27)
	at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:169)
	at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:99)
	at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
	at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
	at com.sun.proxy.$Proxy185.addSystemLog(Unknown Source)
	at com.java2e.martin.common.log.event.LogListener.saveLog(LogListener.java:31)
	at com.java2e.martin.common.log.event.LogListener$$FastClassBySpringCGLIB$$5172b67e.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

原因

RequestContextHolder将当前线程中的request信息存储在ThreadLocal中,开启另外一个线程异步调用feign,httpRequest是绑定在ThreadLocal中的,只能在当前线程中共享,子线程是不能获取到父线程的属性。

解决方案

1、取消异步调用,改为同步调用,如果用的注解,去掉 @Async即可
在这里插入图片描述

2、沿用异步调用,但是在调用前,把父线程request信息绑定给子线程,在方法执行的前面,加入以下语句

RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
  • 1

后记

第二个方案应该也能修复 hystrix 使用线程池导致的RequestContextHolder.currentRequestAttributes()为NULL

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/310046
推荐阅读
相关标签
  

闽ICP备14008679号