项目未使用 AspectJ Maven 正确编译

Project not compiling properly with AspectJ Maven

我正在尝试在 IntelliJ Community Edition.

中使用 AspectJ

它没有按预期工作。我在哪里犯了错误?任何 help/insights 将不胜感激。

技术参考:

  1. IntelliJ IDEA 2018.2.4(社区版)
  2. java版本“1.8.0_77”
package org.kayd;
    
public class Client {
  public static void main(String[] args) {
    Client data = new Client();
    data.data();
  }

  public void data() {
    System.out.println("kayd");
  }
}

看点Class

package org.kayd;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AspectTest {
  @Pointcut("execution(* *(..))")
  public void defineEntryPoint() {}

  @Before("defineEntryPoint()")
  public void log(JoinPoint joinPoint) {
    System.out.println("log");
  }

  @After("execution(org.kayd.Client.data())")
  public void after() {
    System.out.println("log");
  }
}

AOP.xml

<aspectj>
  <aspects>
    <aspect name="org.kayd.AspectTest"/>
  </aspects>
</aspectj>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.kayd</groupId>
  <artifactId>AOP</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.9.2</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.2</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.9</version>
        <configuration>
          <showWeaveInfo>true</showWeaveInfo>
          <source>1.8</source>
          <target>1.8</target>
          <Xlint>ignore</Xlint>
          <complianceLevel>${java.version}</complianceLevel>
          <encoding>UTF-8</encoding>
          <verbose>true</verbose>
        </configuration>
        <executions>
          <execution>
            <phase>process-sources</phase>
            <goals>
              <goal>compile</goal>
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

截图

Ref:我已经研究过这些问题,但仍然没有用。

我只是有一点时间在我的机器上重新创建了你的 Maven 项目。我在评论中所说的实际上是真实的,所以我在这里引用自己的话以将其转化为答案:

At first glance two things strike me as odd:

  • You apply compile-time weaving, but also provide an aop.xml which is only needed for load-time weaving. So which way do you want to go? For CTW you can just remove it.
  • Secondly, the pointcut execution(org.kayd.Client.data()) should yield a compile error because the syntax is invalid (no return type specified for the method signature). You should rather use something like execution(* org.kayd.Client.data()) or execution(void org.kayd.Client.data()).

我想补充一点,不建议使用 after 作为方法名称,因为在 AspectJ 原生语法中它是保留关键字。编译器没有报错,但你还是要小心。

我像这样修改了你的方面以避免 Maven 编译错误,并在控制台上看到更多信息:

package org.kayd;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AspectTest {
  @Pointcut("execution(* *(..))")
  public void defineEntryPoint() {}

  @Before("defineEntryPoint()")
  public void log(JoinPoint joinPoint) {
    System.out.println("Before advice on " + joinPoint);
  }

  @After("execution(org.kayd.Client.data())")
  public void afterAdvice(JoinPoint joinPoint) {
    System.out.println("After advice on " + joinPoint);
  }
}

我还对你的 POM 做了一些调整,因为你一方面使用最新的 AspectJ 版本,但是旧版本的 AspectJ Maven 插件依赖于旧版本,这导致 Maven 控制台上输出奇怪的日志。此外,我添加了一个 One-JAR 打包器和 Maven Exec 插件,因此您可以将整个应用程序放在一个 Über-JAR 中,并且可以 运行 它而无需在类路径上添加任何其他内容。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.kayd</groupId>
  <artifactId>AOP</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.source-target.version>1.8</java.source-target.version>
    <aspectj.version>1.9.2</aspectj.version>
    <main-class>org.kayd.Client</main-class>
  </properties>

  <build>

    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>${java.source-target.version}</source>
            <target>${java.source-target.version}</target>
            <!-- IMPORTANT -->
            <useIncrementalCompilation>false</useIncrementalCompilation>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.11</version>
          <configuration>
            <!--<showWeaveInfo>true</showWeaveInfo>-->
            <source>${java.source-target.version}</source>
            <target>${java.source-target.version}</target>
            <Xlint>ignore</Xlint>
            <complianceLevel>${java.source-target.version}</complianceLevel>
            <encoding>${project.build.sourceEncoding}</encoding>
            <!--<verbose>true</verbose>-->
            <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn>-->
          </configuration>
          <executions>
            <execution>
              <!-- IMPORTANT -->
              <phase>process-sources</phase>
              <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjweaver</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
          </dependencies>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.4.0</version>
          <configuration>
            <mainClass>${main-class}</mainClass>
          </configuration>
        </plugin>
        <plugin>
          <groupId>com.jolira</groupId>
          <artifactId>onejar-maven-plugin</artifactId>
          <version>1.4.4</version>
          <executions>
            <execution>
              <goals>
                <goal>one-jar</goal>
              </goals>
            </execution>
          </executions>
          <configuration>
            <onejarVersion>0.96</onejarVersion>
            <mainClass>de.scrum_master.app.FooBar</mainClass>
            <attachToBuild>true</attachToBuild>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>com.jolira</groupId>
        <artifactId>onejar-maven-plugin</artifactId>
        <configuration>
          <mainClass>${main-class}</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
      </plugin>
    </plugins>

  </build>

  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
  </dependencies>

</project>

然后做类似 mvn clean verify 的事情,然后做这两个中的任何一个:

$ mvn exec:java

[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< org.kayd:AOP >----------------------------
[INFO] Building AOP 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ AOP ---
Before advice on execution(void org.kayd.Client.main(String[]))
Before advice on execution(void org.kayd.Client.data())
kayd
After advice on execution(void org.kayd.Client.data())
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.043 s
[INFO] Finished at: 2018-12-12T12:07:59+07:00
[INFO] ------------------------------------------------------------------------

或者如果你想要 运行 Über-JAR:

$ java -jar target\AOP-1.0-SNAPSHOT.one-jar.jar

Before advice on execution(void org.kayd.Client.main(String[]))
Before advice on execution(void org.kayd.Client.data())
kayd
After advice on execution(void org.kayd.Client.data())