AspectJ切入类列表的所有方法

时间:2014-05-07 20:13:01

标签: aop aspectj pointcut

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

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

(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>

这里出了什么问题?

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

1 个答案:

答案 0 :(得分:1)

关于你的最后评论:除了糟糕的设计之外,我并没有让你感到沮丧,我试图鼓励你做正确的事:重构而不是让自己的生活变得更加艰难。您甚至不知道AspectJ语法的基本知识,但您已经想要实现一个包含大量类的过于复杂的场景,这是一个维护噩梦。我试图通过激励你不做出短视的决定来帮助我。相信我,我已经使用AspectJ多年来所谓的具有大量遗留代码的现实项目。避免即使是最便宜的重构也比进行智能重构要贵得多 - 不是太多,但根据童子军的规则就足够了:让营地落后于比你发现的更清洁。它得到了回报,相信我。

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

  • execution(*.*(..))在语法上是错误的,因为您没有为要匹配的方法指定返回类型(或占位符)。您想使用execution(* *.*(..))或简写版execution(* *(..))
  • 错误&#34;切入点的参数数量不兼容,预期1找到0&#34;不是来自你的切入点,而是来自你甚至没有费心去发布的建议。您必须编写类似@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的执行。