[英]Is it possible to include classes to be weaved by their annotations on aop.xml?
I'm developing some aspects which are expected to load-time weave classes with @AnAnnotation.我正在开发一些方面,这些方面有望在加载时使用@AnAnnotation 编织类。 I created aop.xml as follows
我创建了 aop.xml 如下
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-verbose -showWeaveInfo">
<include within="@com.example.MyAnnotation *" />
</weaver>
<aspects>
<aspect name="com.example.MyAspect" />
</aspects>
</aspectj>
and according to log, my aspect seems to try advise appropriate classes but right after that the following exception occurred.根据日志,我的方面似乎尝试建议适当的课程,但之后发生了以下异常。
java.lang.NoSuchMethodError: com.example.MyAspect.aspectOf
Any ideas?有任何想法吗?
:log :日志
[ERROR] [AppClassLoader@2b193f2d] info AspectJ Weaver Version 1.9.7 built on Thursday Jun 24, 2021 at 16:14:45 PDT
[ERROR] [AppClassLoader@2b193f2d] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@2b193f2d
[ERROR] [AppClassLoader@2b193f2d] info using configuration project/target/classes/META-INF/aop.xml
[ERROR] [AppClassLoader@2b193f2d] info register aspect com.example.MyAspect
[ERROR] [AppClassLoader@2b193f2d] weaveinfo Join point 'constructor-execution(void com.example.MyAspectTest$MyTargetClass.<init>(com.example.MyAspectTest, java.lang.String))' in Type 'com.example.MyAspectTest$MyTargetClass' (MyAspectTest.java:165) advised by afterReturning advice from 'com.example.MyAspect' (MyAspect.java) [with runtime test]
[ERROR] [AppClassLoader@2b193f2d] weaveinfo Join point 'method-execution(void com.example.MyAspectTest$MyTargetClass.myMethod(int))' in Type 'com.example.MyAspectTest$MyTargetClass.' (MyAspectTest.java:182) advised by afterReturning advice from 'com.example.MyAspect' (MyAspect.java) [with runtime test]
[INFO] Running com.example.MyAspectTest
[ERROR] Tests run: 5, Failures: 0, Errors: 5, Skipped: 0, Time elapsed: 0.055 s <<< FAILURE! - in com.example.MyAspectTest
[ERROR] com.example.MyAspectTest.testMyMethod Time elapsed: 0.011 s <<< ERROR!
java.lang.NoSuchMethodError: 'com.example.MyAspect com.example.MyAspect.aspectOf()'
at com.example.MyAspectTest.<init>(MyAspectTest.java:57)
:MyAspect.java :MyAspect.java
package com.example;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@AfterReturning("""
@target(com.example.MyAnnotation)
&& (execution(* *.*(..)) || execution(* .new(..)))
""")
public void intercept(JoinPoint JoinPoint) throws Throwable {
System.out.println("********** MyAspect intercepted");
}
}
There is a subtle error in your aop.xml
:您的
aop.xml
中有一个细微的错误:
<include within="@com.example.MyAnnotation *" />
The include within
rule is too narrow. include within
规则中的范围太窄。 Aspect weaving is falsely limited to only target classes, the aspect class itself is excluded, because it does not carry the target5 annotation itself.方面编织错误地仅限于目标类,方面 class 本身被排除在外,因为它本身不携带 target5 注释。 The effect is that the weaver never finishes the aspect itself - remember, it was not compiled by AJC before.
效果是编织器本身永远不会完成方面 - 请记住,它之前不是由 AJC 编译的。 This caused
NoSuchMethodError: ...MyAspect.aspectOf()
.这导致了
NoSuchMethodError: ...MyAspect.aspectOf()
。 So widening the weaving scope to the whole base package fixes your problem:因此,将编织 scope 扩大到整个基础 package 可以解决您的问题:
<include within="com.example..*" />
Two more things you should improve:还有两点你应该改进:
@within
rather than @target
, because @target
is evaluated dynamically during runtime.@within
而不是@target
,因为@target
在运行时动态评估。 Only then we know for certain which exact type a target instance has.@within
however can be evaluated statically during weaving.@within
可以在编织期间进行静态评估。 Here is my pull request with the three corresponding commits.这是我的三个相应提交的拉取请求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.