【发布时间】:2020-11-16 20:49:37
【问题描述】:
我有这个下面的方面,由于某些原因,你可以看到here,必须使用@EnableAsync 和@Async over aspect 方法,如下所示:
@Aspect
@Component
@EnableAsync
public class ApiCallLogAspect {
@Async
@AfterReturning(value = ("within(com.example..*.web.rest.api..*)"), returning = "returnValue")
public void endpointAfterReturning(JoinPoint p, Object returnValue) throws InterruptedException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
System.out.println(request.getHeader("authorization"));
}
}
现在,我得到了这个异常:
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) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at com.example.web.rest.api.ApiCallLogAspect.endpointAfterReturning(ApiCallLogAspect.java:40) ~[classes/:na]
at com.example.web.rest.api.ApiCallLogAspect$$FastClassBySpringCGLIB$$f034ee12.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_162]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_162]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_162]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_162]
我该如何解决这个问题?有没有办法从
获取请求标头【问题讨论】:
-
请求绑定到一个线程,所以在不同的线程上执行,使得这些东西可以访问。相反,检索您需要的部分,然后开始新的执行。这样您就不需要完整的请求。
-
我该怎么做?你能给我一个示例代码吗?
-
我的评论中已经解释过了。检索标头,将其传递给执行异步的方法(或使用
TaskExecutor提交任务)。它会在设置标头时增加一点延迟,但之后一切都在后台。 -
@M.Deinum 抱歉,我应该在哪里检索标头以及如何将它与任务执行器一起使用?我不熟悉它。
-
在方面。只需删除
@Async,注入TaskExecutor,然后检索信息并使用TaskExecutor.submit或TaskExecutor, execute异步执行任务。
标签: java spring spring-boot request aspect