Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使AspectJ方面在Gradle项目中工作?_Java_Gradle_Aspectj_Aspect - Fatal编程技术网

Java 如何使AspectJ方面在Gradle项目中工作?

Java 如何使AspectJ方面在Gradle项目中工作?,java,gradle,aspectj,aspect,Java,Gradle,Aspectj,Aspect,我使用以下示例代码来理解AspectJ: public class Account { int balance = 20; public boolean withdraw(int amount) { if (balance < amount) { return false; } balance = balance - amount; return true; } pu

我使用以下示例代码来理解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);
    }
}
我正在Intellij中使用Ajc编译器编译Java类和方面。此外,我正在设置以下VM选项:

-javaagent:c:\\Users\\dev\\extlibs\\aspectjweaver-1.9.6.jar

代码编译和运行时没有任何问题,但方面从未触发。我不确定我的配置中缺少了什么,但在使用AspectJ时,我找不到其他可以做的事情。如果我使用@Aspect annotation并在META-INF/aop.xml中注册带注释的方面,则该方面会运行,但带注释的@Aspect Java类不允许创建特权方面,我需要创建特权方面来捕获/截获私有方法。有没有关于如何解决这个问题的建议?

你在那里混合了很多东西:

  • Freefair post编译时编织插件:这是不必要的,因为您有Java源代码,可以使用正常的编译时编织将其与aspect一起编译
  • AspectJ Maven插件:这是无用的,因为您不能简单地在Gradle中使用Maven插件
  • AspectJ加载时编织Java代理:这是不必要的,因为正如我所说的,您可以在这里使用正常的编译时编织。如果不使用
    -javaagent:
    ,也不需要aop.xml
我想您可以使用这三个选项,编译时、编译后和加载时编织,但您应该决定哪一个,而不是混合使用它们。您还应该决定是否要使用Gradle或Maven,也不要尝试混合使用它们

编译时编织就是这样工作的:

  • 将应用程序和方面代码放在目录
    src/main/aspectj
  • 将Gradle构建文件简化为:
  • 插件{
    id“java”
    id“io.freefair.aspectj”版本“5.1.1”
    }
    组“org.example”
    版本“1.0-SNAPSHOT”
    存储库{
    mavenCentral()
    }
    依赖关系{
    实现“org.aspectj:aspectjrt:1.9.6”
    }
    
  • 现在,当从IDE运行主类时,我看到如下内容:
  • >任务:编译无源代码
    >任务:编译最新的SpectJ
    >任务:processResources无源
    >任务:更新课程
    >任务:Account.main()
    [之前]提取,当前余额20
    [周围]退出,检查是否成功
    [提款后]当前余额15
    [之前]提取,当前余额20
    [around]撤消,检查失败
    [之后]提取,当前余额20
    
    当然,如果方面库要用于多个应用程序或模块,或者应用程序源代码不是用Java编写的(例如,用Kotlin、Groovy或Scala编写),因此不能由AspectJ编译器直接编译,那么也可以编译一个单独的方面库并将其编入应用程序代码中。不过,我不打算在这里讨论这个问题,因为我想向您展示最简单的解决方案,因为您似乎是个初学者。(顺便说一句,我也不是Gradle用户,我通常将AspectJ与Maven一起使用。)


    更新:插件文档非常糟糕,但您可以在维护者的GitHub存储库中看到一些:

    • 方面:编译时编织,即一个模块中的应用程序+方面,如我的答案所示
    • httpcore nio:编译后编织到第三方库
    • 测试:如何测试方面
    • 编织:Java、Groovy和Lombok中的混合语言方面,以及如何在单个模块中一起使用它们

    所有这些都可以使用Maven和AspectJ Maven插件来完成,但您特别要求Gradle。

    感谢@kriegaex提供了详尽的答案。现在这很有道理。我已经浏览了很多关于AOP和Aspectj的帖子和示例,没有一个能与你在这里发布的内容相媲美。嗨,Kriegaex,我将build.gradle简化为你发布的版本。我将aspect和Account都放在src/main/java/aspectj中,但aspect似乎并没有起作用。我也试着将它们放入自己的包com.abc.demo中,但仍然没有触发Aspect。这里要补充的一点是,我必须使用Gradle,因为这是这里的标准。我说的是
    src/main/aspectj
    ,而不是
    src/main/java/aspectj
    。好的。这是可行的,但有没有办法,可以在java包中,而不是在src/main/aspecj中?或者它必须存在于src/main/aspectj中?我问的原因是,这是src/main/Java下的一个大型Java项目,我们所有的源代码都在我们的根包中。Kriegaex,我现在明白你为什么说,这必须在src/main/aspectj中,因为这是freefair插件查找方面的默认位置。通过在build.gradle中设置以下属性,我可以使它在src/main/java中工作:sourceSets.main.aspectj.srcDir“src/main/java”sourceSets.main.java.srcDirs=files(),非常感谢您的帮助。
    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")
    }
    
    -javaagent:c:\\Users\\dev\\extlibs\\aspectjweaver-1.9.6.jar