2

我想从类列表(可能属于不同的包)中记录所有方法的条目。请注意,这些方法应仅属于指定的类。

我已经尝试了以下但这些不起作用

(1) 使用 if() 切入点这里出现错误

"incompatible number of arguments to pointcut, expected 1 found 0"

@Pointcut("execution(*.*(..)) && if()")
public static boolean mycut(JoinPoint jp) {
     boolean matches = ... ;//Test using jp if the declaring class belongs to the list
     return matches;
}

(2) 使用 Pointcut 和 aop.xml 的组合 这里我得到一个错误

java.lang.NoSuchMethodError:
com.mypackage.TraceAspect.aspectOf()Lcom/df/jc/aspect/TraceAspect;

//in com.mypackage.TraceAspect aspect class
@Pointcut("execution(*.*(..)) && !within(com.mypackage.TraceAspect)")
public void mycut(){
}

//in aop.xml
<weaver>
    <include within="package1.Class1">
    <include within="package2.Class2">
    <include within="package3.Class3">
</weaver>

这里出了什么问题?

当然可以通过在切入点中单独指定每个类来完成,但这对于数百个类是不可扩展的。理想情况下,如果可以从外部文本文件中获取类列表(以便于配置),那就太好了

4

1 回答 1

2

至于你的最后一条评论:除了糟糕的设计,我并没有劝阻你做任何事情,我试图鼓励你做正确的事情:重构,不要让自己的生活变得比必要的更难。您甚至不了解 AspectJ 语法基础知识,但您已经想要实现一个包含大量类的过于复杂的场景,这是维护的噩梦。我试图通过激励你不要做出短视的决定来提供帮助。相信我,多年来我一直在使用 AspectJ 进行您所谓的具有大量遗留代码的现实项目。避免最便宜的重构比进行智能重构要昂贵得多 - 不是太多,但根据童子军规则就足够了:留下比你找到的更干净的营地。它有回报,相信我。

无论如何,谈论你的代码片段:

  • execution(*.*(..))在语法上是错误的,因为您没有为要匹配的方法指定返回类型(或占位符)。你要使用execution(* *.*(..))的还是速记版本execution(* *(..))
  • 错误“切入点的参数数量不兼容,预期 1 找到 0”不是来自您的切入点,而是来自您甚至没有费心发布的建议。你一定写过类似的东西@Before("mycut()"),但正确的是 @Before("mycut(jp)")

话虽如此,下面是一个简单、完全独立且可编译的示例:

驱动应用:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        System.out.println(multiply(3, add(4, 5)));
    }

    public static int multiply(int i, int j) { return i * j; }
    public static int add(int i, int j) { return i + j; }
}

方面:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class TraceAspect {
    @Pointcut("execution(* *(..)) && if()")
    public static boolean hasMatchingSignature(JoinPoint thisJoinPoint) {
        return !thisJoinPoint.getSignature().getName().equals("main");
    }

    @Before("hasMatchingSignature(thisJoinPoint)")
    public void myAdvice(JoinPoint thisJoinPoint) {
        System.out.println(thisJoinPoint);
    }
}

样本输出:

execution(int de.scrum_master.app.Application.add(int, int))
execution(int de.scrum_master.app.Application.multiply(int, int))
27

如果你的if()切入点只是返回true,输出也会显示main.

于 2014-05-08T09:44:15.743 回答