简体   繁体   English

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

[英]Post-compile weaving aspects into a project using Gradle

Background 背景

Performing post-compile weaving of projects using: 使用以下命令执行项目的编译后编织:

  • AspectJ 1.9.4 AspectJ 1.9.4
  • io.freefair.aspectj.post-compile-weaving 4.1.1 io.freefair.aspectj。编译后编织4.1.1
  • Java 11.0.3 Java 11.0.3
  • Gradle 5.6.2 (Groovy 2.5.4, Kotlin 1.3.41) Gradle 5.6.2(Groovy 2.5.4,Kotlin 1.3.41)

This project does not use Maven or Spring. 该项目不使用Maven或Spring。

Layout 布局

The projects include: 这些项目包括:

  • app.aspects - Contains a single LogAspect class annotated with @Aspect . app.aspects包含一个以@Aspect注释的LogAspect类。
  • app.aspects.weaver - No source files, only dependencies to declare aspects and project to weave. app.aspects.weaver没有源文件,只有依赖关系来声明方面和要编织的项目。
  • app.common - Defines @Log annotation referenced by pointcuts described in LogAspect . app.common定义由LogAspect描述的切入点引用的@Log批注。
  • app.program.main - Files to be woven with jointpoints described in LogAspect . app.program.main要在LogAspect中描述的LogAspect编织的文件。

Gradle 摇篮

Build files that relate to aspects are defined here. 与方面相关的构建文件在此处定义。 The idea is that weaving is independent from the application so neither the application's common classes nor the main program need know about weaving. 想法是编织与应用程序无关,因此应用程序的公共类和主程序都不需要了解编织。 Rather, the main program need only reference @Log from the common package and AJC will take care of the weaving. 相反,主程序只需要引用公共包中的@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 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
    }
}

Classes 班级

Log 日志记录

The Log annotation is straightforward: Log注释很简单:

package com.app.common.aspects;

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

Main Program 主程序

The main program resembles: 主程序类似于:

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

Logging Aspect 记录方面

The logging aspect resembles (see the code from a related question ): 日志记录方面类似(请参阅相关问题中的代码):

@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);
    }
}

Problem 问题

It appears weaving is taking place, but the advice cannot be found: 似乎正在编织,但找不到建议:

.../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] ... / app.aspects / build / classes / java / main!com / app / aspects / LogAspect.class尚未应用com.app.aspects.LogAspect中定义的[警告]建议[Xlint:adviceDidNotMatch]

Question

What needs to change so that weaving of the LogAspect into Program 's run() method works using Gradle? 需要进行哪些更改,以便使用Gradle将LogAspect编织到Programrun()方法中?

Options File 选项文件

The ajc.options file shows: 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

It is disconcerting that -aspectpath isn't shown and -inpath is listing app.aspects instead of app.program.main . 令人不安的是-aspectpath未显示,并且-inpath列出了app.aspects而不是app.program.main

Merging apps.aspects and apps.aspects.weaver into the same project has produced: 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)) 来自'com.app.program.main.Program'类型(com.app.program.main.Program)(Program.java:396)的连接点'method-execution(void com.app.program.main.Program.run())' .app.aspects.LogAspect'(LogAspect.class(来自LogAspect.java))

While this solves the problem, I don't understand why LogAspect needs to be in the same project that performs the weaving. 虽然这解决了问题,但我不明白为什么LogAspect需要位于执行编织的同一项目中。 The Gradle file becomes: 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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM