Aspectj:在aop.xml(LTW)中声明时,Pointcut不再有效

时间:2013-08-10 16:33:05

标签: java aop aspectj pointcut

我试图将我的方面定义为具体方面,以便能够在不编译代码的情况下在aop.xml中定义切入点。我使用的是LTW。

当我在方面类本身中定义我的poincut 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罐。

当我不使用concret-aspects时,请注意以下日志

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

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

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

日志中没有显示错误,看起来好像没有注册concret方面。

请告知。

1 个答案:

答案 0 :(得分:2)

你犯了几个错误:

  • 使用<concrete-aspect>时,具体的切入点应该只在你的 aop.xml 中,而不是在你的代码中。也许这是一个副本&amp;粘贴错误,但在您的示例中,它看起来好像具体切入点已定义两次:代码和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!