1

我试图将我的方面定义为一个具体方面,以便能够在 aop.xml 中定义切入点而无需编译代码。我正在使用 LTW。

当我在切面类本身中定义我的切入点 exp 并将切面定义为一个简单的切面 ( ) 时,它可以正常工作。但是,当我将方面声明为具体方面并在 aop.xml 中定义切入点时。该方面不再起作用......并且它不再达到我建议中的断点......

这是有/没有具体方面的代码:

没有具体方面(工作正常):

public abstract aspect AbstractAspect {
    protected abstract pointcut publicMethod();
}

public aspect MethodExecutionTimeAspect extends AbstractAspect {
    public pointcut publicMethod() : execution(public * com.proj.package..*());
    Object around() : publicMethod() {
        .....
        Object ret = proceed();
        ....
   }
}

和 aop.xml

<aspectj>
    <aspects>
    <aspect  name="com.proj.packae.aspectj.MethodExecutionTimeAspect"/> 
    </aspects>
    <weaver options="-verbose">
    </weaver>
</aspectj>

具体方面(不起作用)

public abstract aspect AbstractAspect {
    protected abstract pointcut publicMethod();
}

public aspect MethodExecutionTimeAspect extends AbstractAspect {
    public pointcut publicMethod() : execution(public * com.proj.package..*());
    Object around() : publicMethod() {
        .....
        Object ret = proceed();
        ....
   }
} 

aop.xml

  <aspectj>
<aspects>

     <concrete-aspect name="com.proj.package.MethodExecutionTimeAspect" extends="com.project.package.aspectj.AbstractAspect">
        <pointcut name="publicMethod" expression="execution(public * com.proj.package..*())" />
    </concrete-aspect>

</aspects>

<weaver options="-verbose">

</weaver>

我正在使用 aspectj 1.6 罐子。

当我不使用具体方面时,以下日志

[WebappClassLoader@7f62cbb2] info register aspect com.project.package.aspectj.MethodExecutionTimeAspect

当我使用具体方面时,我看到以下日志:

[WebappClassLoader@393e11ac] info define aspect com.project.package.aspectj.MethodExecutionTimeAspect

日志上没有显示错误,看起来具体方面没有注册。

请指教。

4

1 回答 1

2

你犯了几个错误:

  • 使用<concrete-aspect>时,具体的切入点应该在您的aop.xml中,而不是在您的代码中。也许这是一个复制和粘贴错误,但在您的示例中,具体切入点似乎被定义了两次:在代码中和在 XML 中。
  • 在具体化抽象方面时,抽象方面必须已经包含要映射到具体切入点的建议。它不能通过 XML 或通过代码和 XML 的组合来覆盖。

看看我自己的例子,和你的很相似:

示例应用:

package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        Application app = new Application();
        app.say("Hello world!");
        app.add(11, 22);
    }

    private int add(int i, int j) { return i + j; }
    public void say(String message) { System.out.println(message); }
}

如您所见,有两种公共方法(一种静态方法,一种非静态方法)和一种私有方法。我这样做是为了测试以后的具体切入点是否真的只捕获公共切入点。

抽象方面:

package de.scrum_master.aspectj;

public abstract aspect AbstractAspect {
    protected abstract pointcut publicMethod();

    Object around() : publicMethod() {
        System.out.println(thisJoinPointStaticPart);
        return proceed();
    }
}

aop.xml:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <concrete-aspect
            name="de.scrum_master.aspectj.ConcreteAspect"
            extends="de.scrum_master.aspectj.AbstractAspect"
        >
            <pointcut
                name="publicMethod"
                expression="execution(public * de.scrum_master..*(..))"
            />
        </concrete-aspect>
    </aspects>
</aspectj>

使用 LTW 时的应用程序输出:

execution(void de.scrum_master.app.Application.main(String[]))
execution(void de.scrum_master.app.Application.say(String))
Hello world!
于 2013-08-10T18:57:25.447 回答