尝试从两个方面包装服务类以获得此调用链:
javanica..HystrixCommandAspect
-> MyCustomAroundAspect
-> MyService
遇到两个问题:
HystrixCommandAspect
不调用joinPoint.proceed()
。相反,它直接在目标类上调用方法,从而有效地跳过了javanica方面之后创建的其他任何代理
Hystrix方面使后续调用在不同的线程中运行。它导致消息:
“未找到MethodInvocation:检查AOP调用正在进行中,并且ExposeInvocationInterceptor
在拦截器中位于前面...”
这是合理的,因为此拦截器将其内容保留在本地线程中。
问题: 1.为什么Spring APO是这样实现的?在不同线程中运行不同方面在概念上是否错误?除了更改方面的顺序之外,还有其他解决方法吗?
HystrixCommandAspect
直接调用目标类而不通过joinPoint.proceed()
调用?它是否违反合同(如果甚至存在)?致谢
答案 0 :(得分:0)
免责声明:我不是Spring或Hystrix用户,而是AOP专家。
为什么
HystrixCommandAspect
直接调用目标类而不通过joinPoint.proceed()
调用目标类?它是否违反合同(如果甚至存在)?
实际上,您必须询问Hystrix维护人员。实际上,这是一个好问题。 Hystrix方面是该宇宙中唯一方面的假设无疑是一个大胆的假设,因为实际上有@Around
建议的AspectJ或Spring AOP合同:
proceed()
。如果继续使用原始方法参数或修改后的参数集,则取决于方面。同样,如果它在执行其他操作之前,之后或之间进行。话虽如此,我认为Hystrix中的一个设计缺陷是不传递ProceedingJoinPoint
并最终对其调用proceed()
,以防最终调用原始方法。如果我是Hystrix用户,那么我将为此打开一个故障单。
此外,从另一个线程中异步调用proceed()
原则上是没有问题的,在创建创建时注入另一个连接点实例的线程。然后,您可以将该线程(或可运行线程)放入队列,并在方便时执行它。从技术上讲,您甚至可以在同一个连接点实例上多次调用proceed()
,但是如果目标方法不是没有副作用的纯函数,则您可能需要注意这一点,除非您的方面实现了某些目标,否则通常不会这样做一种重试方案(有或没有指数补偿)。因此Hystrix也可以做到这一点。如果不这样做,那么他们必须做一些丑陋的事情,例如使用反射调用原始方法。我没有检查。