我正在尝试在 Gradle 项目中启动 AspectJ 代码的简单示例。
构建.gradle:
plugins {
id 'java'
id "io.freefair.aspectj" version "5.1.1"
}
group = 'org.example'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', 'src/main/aspectj']
}
}
test {
java {
srcDirs = ['src/test/java']
}
}
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.23.1'
testImplementation group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.6'
implementation group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.6'
implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.6'
testImplementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.6'
testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2'
testImplementation 'junit:junit:4.13.1'
}
test {
useJUnitPlatform()
}
在文件夹“src/main/aspectj”中,类org.example.aspectj.DemoAspect
package org.example.aspectj;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class DemoAspect {
@Before("execution(* *(..)) && !within(org.example.aspectj.DemoAspect)")
public void logEnter(JoinPoint joinPoint) {
System.out.println("!!!!!!DemoAspect");
System.out.print(joinPoint.getStaticPart());
System.out.print(" -> ");
System.out.println(joinPoint.getSignature());
}
}
在文件夹“src/main/java”中,类org.example.aspectj.Main
package org.example.aspectj;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println("new Date() -> " + new Date());
}
}
我正在上课
Main
。未调用 DemoAspect
中的代码。配置有什么问题吗?
我尝试使用您正在使用的旧插件版本 5.1.1 和 Gradle 6.6.1。如果方面位于 src/main/aspectj 且应用程序类位于 src/main/java 中,则 AspectJ 编译器 (Ajc) 会显示:
[warning] advice defined in org.example.aspectj.DemoAspect has not been applied [Xlint:adviceDidNotMatch]
将所有内容移至 src/main/aspectj 即可正常工作。
我建议升级到最新的 Freefair 插件版本 8.6。现在它不再需要 src/main/aspectj (尽管它仍然可以识别它并且您可以将方面放在那里),但是您可以将所有内容放入 src/main/java 中,这更方便并且也可以在与 AspectJ Maven 插件的做法一致。您可能还想升级到 AspectJ 1.9.21.2,它仍然支持较旧的编译目标,例如 Java 8,但也支持 Java 21。只需确保在 JDK 17+ 上运行构建即可。然后,您的程序可以在较旧的 JRE 上运行,具体取决于
targetCompatibility
。
plugins {
id 'java'
id 'io.freefair.aspectj' version '8.6'
}
group = 'org.example'
version = '1.0-SNAPSHOT'
repositories {
mavenLocal()
mavenCentral()
}
java {
sourceCompatibility = '8'
targetCompatibility = '8'
}
dependencies {
implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.21.2'
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.23.1'
testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2'
testImplementation 'junit:junit:4.13.2'
}
test {
useJUnitPlatform()
}
请注意,您的项目中只需要依赖于
aspectjrt
。该插件将自行确定要使用哪个编译器版本。
package org.example.aspectj;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println("new Date() -> " + new Date());
}
}
我还稍微简化了您的日志输出,只需记录连接点而不是对其进行方法调用。
package org.example.aspectj;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class DemoAspect {
@Before("execution(* *(..)) && !within(org.example.aspectj.DemoAspect)")
public void logEnter(JoinPoint joinPoint) {
System.out.println(joinPoint);
}
}
在 Gradle 8.4 和 JDK 17 或 21 上运行构建,然后主类产生:
Starting Gradle Daemon...
Gradle Daemon started in 2 s 154 ms
> Task :compileJava SKIPPED
> Task :compileAspectj
> Task :processResources NO-SOURCE
> Task :classes
> Task :Main.main()
execution(void org.example.aspectj.Main.main(String[]))
new Date() -> Sun Mar 17 09:16:09 CET 2024