简体   繁体   English

是否可以在 aop.xml 上包含要通过其注释编织的类?

[英]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:还有两点你应该改进:

  • Use @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可以在编织期间进行静态评估。
  • Use AspectJ 1.9.8.RC3 due to use of Java 17 (you seem to like the new text blocks).由于使用了 Java 17(您似乎喜欢新的文本块),因此使用 AspectJ 1.9.8.RC3。 For LTW, this might not be strictly necessary as long as the byte code is compatible, but latest when trying to compile Java 17 code, AspectJ 1.9.7 would not suffice, because it only supports up to Java 15.对于 LTW,只要字节码兼容,这可能不是绝对必要的,但在尝试编译 Java 17 代码时,AspectJ 1.9.7 是不够的,因为它最多仅支持 Java 15。

Here is my pull request with the three corresponding commits.这是我的三个相应提交的拉取请求

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM