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

Post-compile weaving aspects into a project using Gradle

背景

执行post-编译项目编织使用:

此项目未使用 Maven 或 Spring。

布局

项目包括:

Gradle

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

app.aspects

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
}

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
    }
}

日志

Log 注释很简单:

package com.app.common.aspects;

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

主程序

主程序类似于:

package com.app.program.main;

import com.app.common.aspects.Log;

@Log
public class Program {

  /** This is the method to weave. */
  protected void run() throws InterruptedException, TimeoutException {
  }
}

记录方面

日志记录方面类似于(参见 中的代码):

@Aspect
public class LogAspect {

    // In the future this will target points annotated with @Log
    @Pointcut("execution(* com.app.program.main.Program.run(..))")
    public void loggedClass() {
    }

    @Around("loggedClass()")
    public Object log(final ProceedingJoinPoint joinPoint) throws Throwable {
      return log(joinPoint, false);
    }

    private Object log(final ProceedingJoinPoint joinPoint, boolean secure) throws Throwable {
      // See last year's code for the full listing
      log.info("\u21B7| {}{}#{}({})", indent, className, memberName, params);
    }
}

问题

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

.../app.aspects/build/classes/java/main!com/app/aspects/LogAspect.class [warning] advice defined in com.app.aspects.LogAspect has not been applied [Xlint:adviceDidNotMatch]

问题

需要更改什么才能使用 Gradle 将 LogAspect 编织到 Programrun() 方法中?

选项文件

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

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

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

Join point 'method-execution(void com.app.program.main.Program.run())' in Type 'com.app.program.main.Program' (Program.java:396) advised by around advice from 'com.app.aspects.LogAspect' (LogAspect.class(from 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"