[英]How to make an AspectJ Aspect work in a Gradle project?
我正在使用以下示例代碼來理解 AspectJ:
public class Account {
int balance = 20;
public boolean withdraw(int amount) {
if (balance < amount) {
return false;
}
balance = balance - amount;
return true;
}
public static void main(String[] args) {
Account acc = new Account();
acc.withdraw(5);
Account acc2 = new Account();
acc2.withdraw(25);
}
}
和以下方面:
public aspect AccountAspect {
pointcut callWithDraw(int amount, Account acc) :
call(boolean Account.withdraw(int)) && args(amount) && target(acc);
before(int amount, Account acc) : callWithDraw(amount, acc) {
System.out.printf("[before] withDraw, current balance %d%n", acc.balance);
}
boolean around(int amount, Account acc) : callWithDraw(amount, acc) {
if (acc.balance < amount) {
System.out.println("[around] withDraw, check failed");
return false;
}
System.out.println("[around] withDraw, check success");
return proceed(amount, acc);
}
after(int amount, Account acc) : callWithDraw(amount, acc) {
System.out.printf("[after] withDraw, current balance %d%n", acc.balance);
}
}
我正在使用以下 Gradle 構建文件:
plugins {
id 'java'
id "io.freefair.aspectj.post-compile-weaving" version "4.1.4"
}
configurations {
ajc
aspects
aspectCompile
compile{
extendsFrom aspects
}
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.4'
implementation group: 'org.aspectj', name: 'aspectjweaver', version: '1.9.4'
implementation group: 'org.codehaus.mojo', name: 'aspectj-maven-plugin', version: '1.8'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileJava {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
//The following two lines are useful if you have queryDSL if not ignore
dependsOn configurations.ajc.getTaskDependencyFromProjectDependency(true, "compileJava")
}
我在 Intellij 中使用 Ajc 編譯器來編譯 Java 類和方面。 此外,我正在設置以下 VM 選項:
-javaagent:c:\\Users\\dev\\extlibs\\aspectjweaver-1.9.6.jar
代碼編譯並運行沒有任何問題,但方面永遠不會觸發。 我不確定我的配置中缺少什么,但是在使用 AspectJ 時我找不到其他可以做的事情。 如果我使用@Aspect 注釋並在 META-INF/aop.xml 中注冊帶注釋的方面,則方面會運行,但帶注釋的@Aspect Java 類不允許創建我需要捕獲/攔截私有方法的特權方面。 有關如何解決此問題的任何建議?
你在那里混合了很多東西:
-javaagent:
,您也不需要aop.xml 。我想你可以使用所有三個選項,編譯時、編譯后時間和加載時編織,但你應該決定哪一個而不是混合它們。 您還應該決定是否要使用 Gradle 或 Maven 並且不要嘗試混合使用它們。
這就是編譯時編織的工作原理:
src/main/aspectj
中。plugins {
id "java"
id "io.freefair.aspectj" version "5.1.1"
}
group "org.example"
version "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation "org.aspectj:aspectjrt:1.9.6"
}
> Task :compileJava NO-SOURCE
> Task :compileAspectj UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :Account.main()
[before] withDraw, current balance 20
[around] withDraw, check success
[after] withDraw, current balance 15
[before] withDraw, current balance 20
[around] withDraw, check failed
[after] withDraw, current balance 20
當然,您也可以編譯一個單獨的方面庫並將其編織到您的應用程序代碼中,如果要為多個應用程序或模塊重新使用方面庫,或者如果應用程序源代碼不是在 Java 中編寫的(但例如在 Kotlin 中, Groovy 或 Scala),因此不能由 AspectJ 編譯器直接編譯。 不過,我不會在這里討論這個,因為我想向您展示最簡單的解決方案,因為您似乎是初學者。 (順便說一句,我也不是 Gradle 用戶,我通常將 AspectJ 與 Maven 一起使用。)
更新:插件文檔確實很糟糕,但是您可以在維護者的 GitHub 存儲庫中看到一些示例項目:
所有這些也可以使用 Maven 和 AspectJ Maven 插件來完成,但您特別要求 Gradle。
感謝這個線程中的指針,我能夠從 Gradle 成功構建 2 種寫作方面 -
請注意,我使用了 'io.freefair.aspectj.post-compile-weaving' Gradle 插件( https://docs.freefair.io/gradle-plugins/6.0.0-m2/reference/#_io_freefair_aspectj )最簡單的方法是它自動將 Java 類(所有可能的連接點)傳遞到“ajc”中——您需要做的就是將其指向方面本身。
在調試 Gradle 構建過程時,查看生成的ajc 選項被證明是非常有用的。 將這些與https://www.eclipse.org/aspectj/doc/next/devguide/ajc-ref.html進行交叉檢查通常是問題的根源。 它通常與 -inpath 或 -sourceroots 相關。
請注意,屏幕截圖來自 IntelliJ。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.