使用 Gradle 将编织方面后编译到项目中

Dav*_*vis 5 java aop aspectj gradle

背景

使用以下方法执行项目的编译后编织:

  • 方面 1.9.4
  • io.freefair.aspectj.post-compile-weaving 4.1.1
  • Java 11.0.3
  • Gradle 5.6.2(Groovy 2.5.4,Kotlin 1.3.41)

该项目不使用 Maven 或 Spring。

布局

这些项目包括:

  • app.aspects- 包含一个LogAspect@Aspect.
  • app.aspects.weaver - 没有源文件,只有声明方面的依赖项和要编织的项目。
  • app.common- 定义@Log由 中描述的切入点引用的注释LogAspect
  • app.program.main- 文件将与LogAspect.

摇篮

与方面相关的构建文件在此处定义。这个想法是编织独立于应用程序,因此应用程序的公共类和主程序都不需要知道编织。相反,主程序只需@Log要从公共包中引用,AJC 将负责编织。

应用程序方面

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    // For the @Log annotation
    compileOnly project(':app.common')

    // The LogAspect's joinpoint references the Main Program
    compileOnly project(':app.program.main')

    // Logging dependency is also compiled, but not shown here
}
Run Code Online (Sandbox Code Playgroud)

app.aspects.weaver

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    compileOnly "org.aspectj:aspectjrt:1.9.4"

    // This should set the -aspectpath ?
    aspect project(":app.aspects")

    // This should set the -inpath ?
    inpath(project(":app.program.main")) {
        // Only weave within the project
        transitive = false
    }
}
Run Code Online (Sandbox Code Playgroud)

班级

日志

Log注释很简单:

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    // For the @Log annotation
    compileOnly project(':app.common')

    // The LogAspect's joinpoint references the Main Program
    compileOnly project(':app.program.main')

    // Logging dependency is also compiled, but not shown here
}
Run Code Online (Sandbox Code Playgroud)

主程序

主程序类似于:

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    compileOnly "org.aspectj:aspectjrt:1.9.4"

    // This should set the -aspectpath ?
    aspect project(":app.aspects")

    // This should set the -inpath ?
    inpath(project(":app.program.main")) {
        // Only weave within the project
        transitive = false
    }
}
Run Code Online (Sandbox Code Playgroud)

日志方面

日志方面类似于(请参阅相关问题中的代码):

package com.app.common.aspects;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE, ElementType.CONSTRUCTOR })
public @interface Log {
    boolean secure() default false;
}
Run Code Online (Sandbox Code Playgroud)

问题

似乎正在编织,但找不到建议:

.../app.aspects/build/classes/java/main!com/app/aspects/LogAspect.class [警告] com.app.aspects.LogAspect 中定义的建议尚未应用 [Xlint:adviceDidNotMatch]

需要更改什么才能使用 Gradle编织LogAspectintoProgramrun()方法?

选项文件

ajc.options文件显示:

-inpath
.../app.aspects/build/classes/java/main
-classpath
.../.gradle/caches/modules-2/files-2.1/org.aspectj/...
-d
.../app.aspects/build/classes/java/main
-target
11
-source
11
Run Code Online (Sandbox Code Playgroud)

令人不安的-aspectpath是没有显示并且-inpath列出app.aspects而不是app.program.main

Dav*_*vis 1

合并apps.aspectsapps.aspects.weaver同一个项目中产生了:

在类型“com.app.program.main.Program”(Program.java:396)中加入点“method-execution(void com.app.program.main.Program.run())”,由“com”的周围建议建议.app.aspects.LogAspect'(LogAspect.class(来自LogAspect.java))

虽然这解决了问题,但我不明白为什么LogAspect需要在执行编织的同一个项目中。Gradle 文件变为:

apply plugin: "io.freefair.aspectj.post-compile-weaving"

dependencies {
    compileOnly "org.aspectj:aspectjrt:1.9.4"
    compileOnly project(':app.common')
    compileOnly project(':app.program.main')

    compileOnly org_apache_logging_log4j__log4j_api

    inpath(project(":app.program.main")) {
        transitive = false
    }
}

compileJava.ajc.options.compilerArgs += "-showWeaveInfo"
compileJava.ajc.options.compilerArgs += "-verbose"
Run Code Online (Sandbox Code Playgroud)