gpt4 book ai didi

java - 跨多个线程的 Spring 方面

转载 作者:行者123 更新时间:2023-12-01 17:16:10 27 4
gpt4 key购买 nike

尝试用两个方面包装服务类来获取此调用链:

javanica..HystrixCommandAspect -> MyCustomAroundAspect -> MyService

遇到两个问题:

  1. HystrixCommandAspect 不会调用 joinPoint.proceed()。相反,它直接调用目标类上的方法,这有效地跳过了 javanica 方面之后创建的任何其他代理

  2. Hystrix 方面使后续调用在不同的线程中运行。它导致消息:

    “未找到 MethodInitation:检查 AOP 调用是否正在进行,以及 ExposeInvocalInterceptor 是否位于拦截器的前面...”

这是合理的,因为这个拦截器将其内容保存在线程本地。

问题:1. Spring APO为什么要这样实现?在不同线程中运行不同方面在概念上是错误的吗?除了更改方面的顺序之外还有其他解决方法吗?

  • 为什么HystrixCommandAspect直接调用目标类,而不是通过joinPoint.proceed()?它不会违反契约(Contract)(如果存在的话)吗?
  • 问候

    最佳答案

    免责声明:我不是 Spring 或 Hystrix 用户,只是 AOP 人员。

    Why does HystrixCommandAspect call target class directly, but not through joinPoint.proceed()? Doesn't it break the contract (if one even exists)?

    实际上,你得问Hystrix维护者。实际上,这是一个好问题。 Hystrix 方面是这个宇宙中唯一的方面的假设无疑是一个大胆的假设,因为实际上有一个用于 @Around 建议的 AspectJ 或 Spring AOP 契约:

    • 方面调用原始方法。如果这样做,它应该使用proceed()。如果它继续使用原始方法参数或修改后的集合,则取决于方面。此外,如果它在做其他事情之前、之后或之间进行。
    • 或者方面返回计算结果(对于非 void 方法),而不继续执行原始方法。
    • 或者方面抛出异常,不返回任何结果。

    话虽如此,我认为 Hystrix 中的一个设计缺陷是不传递 ProceedingJoinPoint 并最终调用 proceed() 以防原始方法是最终被调用。如果我是 Hystrix 用户,我会为此开一个错误票。

    此外,从创建时注入(inject)连接点实例的另一个线程异步调用 proceed() 原则上没有问题。然后,您可以将该线程(或可运行线程)放入队列中并在方便时执行它。从技术上讲,您甚至可以在同一个连接点实例上多次调用 proceed() ,但如果目标方法不是没有副作用的纯函数,您可能需要小心,并且通常不会这样做除非你的方面实现了某种重试方案(有或没有指数退避)。所以 Hystrix 也可以做到这一点。如果他们不这样做,那么他们一定在做一些丑陋的事情,例如使用反射来调用原始方法。我没有检查。

    关于java - 跨多个线程的 Spring 方面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61382250/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com