如何实现扩展抽象方面的具体方面
How to implement concrete aspect extending abstract aspect having field with annotations eligible for load time weaving in aspect itself
我在 aspectJ 中实现具体方面时遇到问题。下面是相关的代码片段。我有两个抽象方面 - FieldAspect.java
和 AbstractTracing.java
。我在 xml - ConcreteTracingimpl
和 MyFieldAspect
中定义具体方面,这不是通过代码。在 Main.java
中,我正在调用 Test.getTestMethod()
,因此,在调用此方法之前,由于注释 @method
,AbstractTracing.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 指向的代码的限制(即方法必须是静态的)——我不知道这对您是否合适?您发现的问题绝对是一个错误(请提出),我只是提供这种表达方面的替代方法作为解决方法。
我在 aspectJ 中实现具体方面时遇到问题。下面是相关的代码片段。我有两个抽象方面 - FieldAspect.java
和 AbstractTracing.java
。我在 xml - ConcreteTracingimpl
和 MyFieldAspect
中定义具体方面,这不是通过代码。在 Main.java
中,我正在调用 Test.getTestMethod()
,因此,在调用此方法之前,由于注释 @method
,AbstractTracing.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 指向的代码的限制(即方法必须是静态的)——我不知道这对您是否合适?您发现的问题绝对是一个错误(请提出),我只是提供这种表达方面的替代方法作为解决方法。