【问题标题】:Can't find referenced pointcut [functionName]找不到引用的切入点 [functionName]
【发布时间】:2022-02-07 10:08:33
【问题描述】:

我正在尝试扩展包含 AspectJ 建议的 abstract class。我的实现很简单:

@Aspect
public class XRayInterceptor extends BaseAbstractXRayInterceptor {
    @Pointcut("execution(public * *(..))")
    private void publicMethods() {}

    @Pointcut("@within(com.amazonaws.xray.spring.aop.XRayEnabled)")
    private void xrayAnnotatedClass() {}

    @Pointcut("xrayAnnotatedClass() && publicMethods()")
    protected void xrayEnabledClasses() {}
}

不幸的是,编译时我从iajc 收到以下错误(添加了换行符):

[iajc] [error 0]:
    error at com/amazonaws/xray/spring/aop/BaseAbstractXRayInterceptor.java::0
    can't find referenced pointcut xrayEnabledClasses

我不明白为什么它抱怨 BaseAbstractXRayInterceptor 是一个抽象类并且没有被直接使用。

现在我只是简单地复制了抽象类,使其具体化并添加了上面的切入点来让我畅通无阻。

有什么想法吗?谢谢!

【问题讨论】:

  • 问一个关于基类中的错误消息的问题并不是那么有帮助,你在这里对我们隐藏了。请了解MCVE 是什么以及它如何通过使您的问题可重现来帮助您获得有用的答案。你的孩子方面对我来说看起来不错,但我需要看到全貌。我也想知道你的 AspectJ 版本,如果你使用 CTW 或 LTW,甚至可能是 Spring AOP 而根本不使用 AspectJ。
  • 我会在 4 天后收到一些反馈。我的回答应该已经解释了你的情况出了什么问题,即使我只有很少的信息可以使用,并且不得不尝试从你的代码和错误日志中提取信息,比如 Sherlock Holmes。如果您不理解我的解释,请接受并支持我的回答或在评论中提出后续问题。谢谢。
  • 感谢您对问题的反馈。以供将来参考,是否提供指向直接指向被视为“隐藏”的类的 github 存储库的链接?我是否更喜欢复制整个基类?
  • 您可以发布一个完整的方面类与导入。您还可以提到基类所在的依赖项 Maven 或 Gradle 坐标。在这种情况下,我自己找到了它,正如您在我的回答中看到的那样,因为我从错误消息中推断出它并在网上搜索它以便更好地了解情况。但实际上我的工作不是搜索您已经拥有的信息,并且可以轻松地在您的问题中提供作为上下文的信息。但是不,如果您告诉我在哪里可以找到它,则无需在此处粘贴公开可用的 3rd 方类。 ??????
  • 这个问题仍然被列为未接受,尽管我认为我正确地回答了它并且也发表了广泛的评论。请问您还等什么?

标签: aop aspectj


【解决方案1】:

我讨厌在没有MCVE 的情况下进行推测,所以这个答案不是确定的,现在只是一个有根据的猜测:

看着BaseAbstractXRayInterceptor source code,...

public abstract class BaseAbstractXRayInterceptor {
  // (...)

  @Around("xrayTracedClasses() || xrayEnabledClasses()")
  public Object traceAroundMethods(ProceedingJoinPoint pjp) throws Throwable {
    return this.processXRayTrace(pjp);
  }

  // (...)

  @Pointcut("execution(* XRayTraced+.*(..))")
  protected void xrayTracedClasses() {}

  // (...)
}

我可以看到基类没有被声明为@Aspect,即它不能用本机 AspectJ 编译器编译或被 AspectJ 用作另一个本机方面的基类。 更新: AspectJ 要求它的基类也是一个方面。但是,如果在基类中没有 @Aspect 声明,则违反了该规则。 我们在这里看到的内容仅适用于 Spring AOP。包名com.amazonaws.xray.spring.aop 也暗示了Spring AOP,尽管它并不能证明什么。

然而,出于某种原因,您似乎正在尝试使用 AspectJ 编译器来编译您自己的方面,显然是使用相应的 Ant 任务。 (我建议改用 Maven,但这不在此处。)在这种情况下,AspectJ 编译步骤不仅没有必要,而且会适得其反。

我认为,假设您在 Spring 上下文中工作,您应该只在 Spring AOP 中使用您的方面。如果您将@Component 注释添加到XRayInterceptor 方面,则组件扫描可以获取该方面。否则,您也可以声明一个@Bean 工厂方法来实例化方面,但这更繁琐。我推荐组件扫描。

【讨论】:

  • 感谢您的回复!对延迟回复您表示歉意。需要明确的是,我无法分享太多信息以使其成为可重现的错误。我可以分享的是,我们没有使用 Spring AOP,我们在使用 Guice 构建的应用程序中使用 vanilla AspectJ 1.9 版。至于 CTW 与 LTW,我自己有点困惑,因为我们确实有一些指向 LTW 的配置和其他指向 CTW 的配置。两者都有可能吗?
  • > 在这种情况下,AspectJ 编译步骤不仅没有必要,而且会适得其反。您能详细说明以上内容吗?为什么它是不必要的和适得其反的?我的印象是,如果我需要通过 AspectJ 编译器运行方面来添加基础架构代码,例如aspectOf(),否则运行时会失败。
  • 您似乎没有阅读我现在第二次在这里发布的MCVE 文章的链接。我不需要您的原始应用程序,而是它的最小版本,其中没有任何公司特定的东西,它仍然会重现问题。尽可能多地剥离,重命名包和类,然后将其发布到 GitHub 存储库中。如果你坚持的话,一个 Maven 项目会很棒,Gradle。说“我不能共享一个 MCVE”是一个不值得任何开发者的声明,恕我直言。我无法调试散文。
  • 我关于编译会适得其反的陈述是基于您使用 Spring AOP 而不是本机 AspectJ 的假设,因为您使用了为 Spring AOP 设计的超类。我想停止猜测。就像我在回答开头所说的那样,我讨厌这样并且已经后悔我这样做了,因为它只是引发了这场讨论,而不是回答一个直接的问题。所以你现在有一个选择:请提供一个 MCVE,这样我就可以分析而不是推测。否则,我们就在这里完成。我确实想帮忙,但不是这样。
  • 请注意我在斜体中的回答中的“更新”部分。我试图更准确地解释一个方面的非方面基类在本机 AspectJ 中不起作用,仅在 Spring AOP 中起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
相关资源
最近更新 更多