Pav*_*vel 3 java aop spring asynchronous
我有我的ControllerLogger类,它有一些方法与@Before和@AfterReturning注释。
如果我把@Async它们都放在一起,它们会开始异步执行@EnableAsync吗?
那么如何为这些方法解析和创建代理,它们将如何?
kri*_*aex 13
在阅读您的问题时,首先让我印象深刻的是:您为什么不尝试而不是在这里提出问题并等待答案?一分钟后你就知道了。
第二个问题是:为什么每次执行方面的建议时都想创建一个新任务?那真的会比同步执行更快吗?从你的方面名称ControllerLogger我得出结论,它所做的只是记录。但无论如何,也许你的日志记录太慢了,让它异步实际上是有意义的。通常你已经可以为你的日志框架配置它,所以方面不需要照顾它。
最后回答你的问题:我自己之前从未尝试过,但我花了两分钟来测试:
System.out.println(Thread.currentThread() + " -> " + Thread.currentThread().getId());在方面建议和目标方法中添加类似语句。@Async/运行@EnableAsync。注意结果。@Async/ @EnableAsync。注意结果。对我来说,我以前看到过这样的事情:
Thread[main,5,main] -> 1
Thread[main,5,main] -> 1
Thread[main,5,main] -> 1
Thread[main,5,main] -> 1
Run Code Online (Sandbox Code Playgroud)
这在激活异步执行之后(执行了 3 个方面建议):
Thread[main,5,main] -> 1
Thread[SimpleAsyncTaskExecutor-1,5,main] -> 18
Thread[SimpleAsyncTaskExecutor-2,5,main] -> 25
Thread[SimpleAsyncTaskExecutor-3,5,main] -> 26
Run Code Online (Sandbox Code Playgroud)
所以答案是:是的,像@Before或@After用于 Spring AOP 的方面建议将异步执行。
但是要小心@Around通知,因为如果目标方法(以及周围的通知)返回voidor以外的类型Future(如@Async注释的 Javadoc 中所述),您将获得运行时异常,因为异步执行的通知将返回null到被拦截的先说方法。所以你会看到这样的异常:
Exception in thread "main"
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public int spring.aop.MyController.doSomething(java.lang.String,int)
at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:362)
at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:84)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:658)
at spring.aop.MyController$$EnhancerBySpringCGLIB$$c28d13a5.doSomething(<generated>)
at spring.aop.DemoApplication.main(DemoApplication.java:28)
Run Code Online (Sandbox Code Playgroud)
因此,请确保仅在异步执行实际上有意义并且设计了注释的情况下才使用@Async+ @Around。
更新:上面的异常只会出现在返回原始类型的方法中,例如,如果您的方法返回 anint并且一个 around 建议被执行并调用JoinPoint.proceed(). 如果相同的方法会返回Integer,那么 around 建议将执行而不会出错,但是 return null,这是您的调用者不期望的并且可能会破坏您的程序。所以正如我所说,小心如何将它与@Around.
更新 2:即使目标方法返回 aFuture但围绕建议返回其他内容,例如Object,proceed()将返回null。只有当你让 around 通知也有一个返回类型时Future,它才真正起作用,调用者可以按预期处理未来,等待isDone()实际收到预期结果后。
| 归档时间: |
|
| 查看次数: |
2603 次 |
| 最近记录: |