如何实现扩展抽象方面的具体方面

How to implement concrete aspect extending abstract aspect having field with annotations eligible for load time weaving in aspect itself

我在 aspectJ 中实现具体方面时遇到问题。下面是相关的代码片段。我有两个抽象方面 - FieldAspect.javaAbstractTracing.java。我在 xml - ConcreteTracingimplMyFieldAspect 中定义具体方面,这不是通过代码。在 Main.java 中,我正在调用 Test.getTestMethod(),因此,在调用此方法之前,由于注释 @methodAbstractTracing.java 中的 around 建议得到应用,但 AbstractTracing.java 也有一个用 @field 注释注释的静态字段,因此,该字段应该用值 andy 初始化 但它是空的。

如果抽象方面包含带注释的字段,并且这些字段适用于加载时编织,应该如何实现?请指导我。非常感谢。

AbstractTracing.java

package main.java.aop.extend;
import main.java.aop.field.Field;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;. 
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public abstract class AbstractTracing {

@Field
static String x;

@Pointcut
public abstract void trace();

@Around("trace()")
public void traceMethod() {
    System.out.println("In trace method of AbstractTracing class : " + x);
 }   

}

FieldAspect.java

package main.java.aop.field;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public abstract class FieldAspect {
@Pointcut
public abstract void getField();

@Around("getField()")
public String getFieldValue() {     
    return "Andy";
 }  
}

aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
<aspects>
<concrete-aspect name="main.java.aop.extend.ConcreteTracingimpl"
        extends="main.java.aop.extend.AbstractTracing">
        <pointcut name="trace"
            expression="execution(@main.java.aop.method.Method * * (..))" />
    </concrete-aspect>
<concrete-aspect name="main.java.aop.field.MyFieldAspect"
        extends="main.java.aop.field.FieldAspect">
        <pointcut name="getField" expression="get(@main.java.aop.field.Field * *)" />
    </concrete-aspect>
<weaver options="-verbose -showWeaveInfo" />
</aspectj>

Field.java

package main.java.aop.field;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Field {
}

Method.java

package main.java.aop.field;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Method {
}

Main.java

package main.java.aop.main;

import main.java.aop.extend.Test;

public class Main {

public static void main(String[] args) {

    System.out.println("<---------- EXTENDS example ---------->");
    Test.testMethod();
 }
}

Test.java

package main.java.aop.extend;

import main.java.aop.method.Method;

public class Test {

@Method
public static void testMethod() {
    System.out.println("calling test method in test class");
 }
}

有趣的情况,看起来像是 AspectJ 错误。据我所见,抽象方面本身并没有传递给编织者进行编织。我们可以看到,如果你在weaver选项中打开附加标志(-debug):

[AppClassLoader@58644d46] info AspectJ Weaver Version 1.8.4 built on Thursday Nov 6, 2014 at 20:19:21 GMT
[AppClassLoader@58644d46] info register classloader sun.misc.Launcher$AppClassLoader@58644d46
[AppClassLoader@58644d46] info using configuration /Users/aclement/play/sridhar/META-INF/aop.xml
[AppClassLoader@58644d46] info define aspect main.java.aop.extend.ConcreteTracingimpl
[AppClassLoader@58644d46] info define aspect main.java.aop.field.MyFieldAspect
[AppClassLoader@58644d46] debug weaving 'main.java.aop.extend.ConcreteTracingimpl'
[AppClassLoader@58644d46] debug generating class 'main.java.aop.extend.ConcreteTracingimpl'
[AppClassLoader@58644d46] debug weaving 'main.java.aop.field.MyFieldAspect'
[AppClassLoader@58644d46] debug generating class 'main.java.aop.field.MyFieldAspect'
[AppClassLoader@58644d46] debug weaving 'main.java.aop.main.Main'
[AppClassLoader@58644d46] weaveinfo Join point 'field-get(java.lang.String main.java.aop.extend.AbstractTracing.x)' in Type 'main.java.aop.main.Main' (Main.java:11) advised by around advice from 'main.java.aop.field.MyFieldAspect' (FieldAspect.java:7)
<---------- EXTENDS example ---------->
[AppClassLoader@58644d46] debug weaving 'main.java.aop.extend.Test'
[AppClassLoader@58644d46] weaveinfo Join point 'method-execution(void main.java.aop.extend.Test.testMethod())' in Type 'main.java.aop.extend.Test' (Test.java:8) advised by around advice from 'main.java.aop.extend.ConcreteTracingimpl' (AbstractTracing.java)
[AppClassLoader@58644d46] debug generating class 'main.java.aop.extend.Test$AjcClosure1'
[AppClassLoader@58644d46] debug cannot weave 'org.aspectj.lang.NoAspectBoundException'
In trace method of AbstractTracing class : null

现在为什么没有传递给织布工,问得好。可能是重新进入守卫已经到位,以阻止编织者一旦已经在做某事就进入自己。

不过,我做了一些改动,可以让它正常工作,我使用了一个隐藏在其中一个发布自述文件中的特殊功能。当你拥有像你这样的方面时,你实际上可以在 XML 中定义整个方面,只需使用代码来保存行为,你不需要任何方面注释。所以如果我像这样重写你的抽象方面:

package main.java.aop.field;

class FieldAspect {
  static String getField() {
    return "Andy";
  }
}

package main.java.aop.extend;

public class AbstractTracing {

  @Field
  public static String x;

  public static void traceMethod() {
    System.out.println("In trace method of AbstractTracing class : " + x);
  }   

}

然后这个aop.xml:

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
<aspects>

  <concrete-aspect name="main.java.aop.field.MyFieldAspect">
    <around pointcut="get(@main.java.aop.field.Field * *)" invokeClass="main.java.aop.field.FieldAspect" invokeMethod="getField()"/>
  </concrete-aspect>

  <concrete-aspect name="main.java.aop.extend.ConcreteTracingImpl">
    <around pointcut="execution(@main.java.aop.method.Method * *(..))" invokeClass="main.java.aop.extend.AbstractTracing" invokeMethod="traceMethod()"/>
  </concrete-aspect>

</aspects>
<weaver options="-verbose -showWeaveInfo" />
</aspectj>

(关于此功能的文档在这里:http://www.eclipse.org/aspectj/doc/released/README-1612.html

现在当我运行它

[AppClassLoader@58644d46] info AspectJ Weaver Version 1.8.4 built on Thursday Nov 6, 2014 at 20:19:21 GMT
[AppClassLoader@58644d46] info register classloader sun.misc.Launcher$AppClassLoader@58644d46
[AppClassLoader@58644d46] info using configuration /Users/aclement/play/sridhar/META-INF/aop.xml
[AppClassLoader@58644d46] info define aspect main.java.aop.field.MyFieldAspect
[AppClassLoader@58644d46] info define aspect main.java.aop.extend.ConcreteTracingImpl
<---------- EXTENDS example ---------->
[AppClassLoader@58644d46] weaveinfo Join point 'method-execution(void main.java.aop.extend.Test.testMethod())' in Type 'main.java.aop.extend.Test' (Test.java:8) advised by around advice from 'main.java.aop.extend.ConcreteTracingImpl' (no debug info available)
[AppClassLoader@58644d46] weaveinfo Join point 'field-get(java.lang.String main.java.aop.extend.AbstractTracing.x)' in Type 'main.java.aop.extend.AbstractTracing' (AbstractTracing.java:13) advised by around advice from 'main.java.aop.field.MyFieldAspect' (no debug info available)
In trace method of AbstractTracing class : Andy

可以看到'abstract aspects'中的连接点正在编织中。但是,您从 XML 指向的代码的限制(即方法必须是静态的)——我不知道这对您是否合适?您发现的问题绝对是一个错误(请提出),我只是提供这种表达方面的替代方法作为解决方法。