BeforeAspect.java
@Aspect
@Component
@EnableAsync
public class BeforeAspect {
@Pointcut("@annotation(com.example.demo.api.EventLog)")
public void eventLogControllers() {}
@Before("eventLogControllers()")
@Async
public void beforeController(JoinPoint BeforeJoinPoint){
HttpServletRequest requestAttributes=((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
System.out.println("Before LocalName: "+requestAttributes.getLocalName());
System.out.println("Before Request URL: "+requestAttributes.getRequestURL());
}
}
Controller.java
@RequestMapping("employee")
@RestController
public class Controller {
EmployeeService empser;
@Autowired
public Controller(EmployeeService empser) {
this.empser = empser;
}
@GetMapping
@EventLog
public List<Employee> selectemployees(){
return empser.findallemployees();
}
}
EventLog.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EventLog {
}
当我运行应用程序时,我得到以下错误
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.10.RELEASE.jar:5.2.10.RELEASE]
at com.example.demo.EventAspects.BeforeAspect.beforeController(BeforeAspect.java:37) ~[classes/:na]
at com.example.demo.EventAspects.BeforeAspect$$FastClassBySpringCGLIB$$e508b82a.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
当我试图访问employee api时,我得到了上面的错误。我的要求是,我需要在AOP before通知(Aspectj)中创建异步AOP,并在异步before方法中访问请求细节。如果该方法不是异步的,那么它工作得很好。有没有一种方法可以将RequestContextHolder作为参数传递给之前的方法?或者有没有其他方法可以访问它。
发布于 2021-08-16 03:31:53
我不是Spring用户,但有时会尝试用我的AOP知识来帮助Spring AOP用户。这是关于Spring的@Async
特性的更多内容,所以我对此不是很了解。
Here是一些关于异步AOP通知的一般信息,以及关于@Around
的额外信息,这似乎不是您关注的重点。但也许你可以从我的答案中提取一些有用的东西。
至于你的用例,你显然是在强迫某些东西是异步的,而这些东西应该是同步的。您只说希望通知异步运行,但没有解释原因。它同步地工作得很好,为什么要费心去破坏一个正常工作的系统呢?你的外貌真的这么慢吗?去优化它吧!
如果您坚持让它异步,为什么不遵循错误消息中给出的建议呢?引用:
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.
https://stackoverflow.com/questions/68782538
复制相似问题