簡體   English   中英

在 Maven 項目中未觸發 AspectJ 方面

[英]AspectJ Aspects not getting triggered in Maven Project

我正在嘗試使用AspectJ構建 POC 項目而不使用Spring AOP 我正在使用基於注釋的方法,我想在其中運行方面@Around已使用注釋進行注釋的方法。 出於某種原因,我的方面沒有被觸發。 下面是我的代碼:

pom.xml

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.9</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <Xlint>ignore</Xlint>
                <encoding>UTF-8</encoding>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <!-- use this goal to weave all your main classes -->
                        <goal>compile</goal>
                        <!-- use this goal to weave all your test classes -->
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

資源/META-INF/aop.xml

<aspectj>
    <aspects>
        <aspect name="com.aditya.personal.aspects.MetricsAspect"/>
        <weaver options="-verbose -showWeaveInfo">
            <include within="com.carrot.personal.aspects.*"/>
        </weaver>
    </aspects>
</aspectj>

我的觀點:

@Aspect
public class DataTrackAspect {

    @Around("@annotation(com.carrot.personal.aspects.DataTrackEnabled)")
    public Object performAspect(ProceedingJoinPoint joinPoint, DataTrackEnabled dataTrackEnabled) throws Throwable {

        Object result = joinPoint.proceed();
        DataTrackHelper dataTrackHelper = new DataTrackHelper();
        dataTrackHelper.recordInstanceCount(dataTrackEnabled.dataClass(), dataTrackEnabled.dataName(), dataTrackEnabled.instance());
        return result;
    }
}

帶注釋的方法

@DataTrackEnabled(dataClass = "Hey", dataName = "There", instance = "How are you?")
public Map<String, String> fetchUser() {
    Map<String, String> returnable = new HashMap<>();
    returnable.put("firstName", "carrot");
    returnable.put("lastName", "radish");
    return returnable;
}

我似乎無法弄清楚我錯過了什么。 在這里上傳了 GitHub 上的示例代碼。

您正在使用 AspectJ Maven 插件,即您將使用編譯時編織。 因此,您不需要 aop.xml,因為它用於加載時編織。 所以你可以刪除它。

在編譯期間,您應該得到一個編譯錯誤:

Unbound pointcut parameter 'dataTrackEnabled'

這告訴您您的通知方法有一個參數dataTrackEnabled ,它不會出現在切入點的任何地方,因為它應該出現。 所以只需將切入點從

@Around("@annotation(com.carrot.personal.aspects.DataTrackEnabled)")

@Around("@annotation(dataTrackEnabled)")

如您所見,我指的是切入點中的方法參數名稱。 如果您不將注釋綁定到參數,那么您將需要之前使用的完全限定的 class 名稱。

此外,您的 Maven POM 應該會導致此錯誤:

diamond operator is not supported in -source 1.5

這是因為使用 AspectJ Maven 不會自動停用或替換 Maven 編譯器插件,后者抱怨您沒有為其設置源和目標版本。 所以你有兩個選擇:

  1. 停用 Maven 編譯器,讓 AspectJ Maven 編譯您的 Java 和方面類。
  2. 將 Maven 編譯器的編譯器級別設置為 1.8(或簡稱為 8),並為 AspectJ Maven 使用相同的設置。

我會選擇選項號。 2 在這種情況下。 Maven 知道名為maven.compiler.sourcemaven.compiler.target的屬性。 讓我們定義和使用它們:

  <!-- (...) -->

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
  </properties>

  <!-- (...) -->

        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
          <complianceLevel>${maven.compiler.target}</complianceLevel>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>

  <!-- (...) -->

現在還有一些警告:

Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!

File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!

bad version number found in C:\Users\alexa\.m2\repository\org\aspectj\aspectjrt\1.8.9\aspectjrt-1.8.9.jar expected 1.8.2 found 1.8.9

前兩個只是因為您忘記設置<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 當您使用它時,您也可以為生成的報告設置編碼: <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

最后一個與方面相關,因為AspectJ Maven 1.7 取決於 AspectJ 1.8.2 ,而不是 1.8.9。 但小心點! 它依賴於aspectjtools (用於使用編譯器),而不是aspectjweaver (用於加載時編織)。 您可以升級版本或覆蓋插件內的依賴項。 為了以防萬一,我將同時向你們展示兩者。

最后但同樣重要的是,AspectJ 1.8 的最新版本是 1.8.13。 但是您可以只使用最新版本 1.9.6,它支持高達 Java 14(Java 15+16 的下一個版本幾乎准備就緒)並且仍然可以生成 ZD52187878D8759EA22 的字節碼。

這個POM怎么樣?

<?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>com.carrot</groupId>
  <artifactId>SO_AJ_MavenProjectNotWorking_66734262</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <aspectj.version>1.9.6</aspectj.version>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
          <complianceLevel>${maven.compiler.target}</complianceLevel>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
          <showWeaveInfo>true</showWeaveInfo>
          <verbose>true</verbose>
          <Xlint>ignore</Xlint>
          <encoding>UTF-8</encoding>
        </configuration>
        <executions>
          <execution>
            <goals>
              <!-- use this goal to weave all your main classes -->
              <goal>compile</goal>
              <!-- use this goal to weave all your test classes -->
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>

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

</project>

現在,當您運行程序時,您應該會看到如下內容:

Recording: dataClass = Hey, dataName = There, instance = How are you?
Recording: dataClass = Hey, dataName = There, instance = How are you?

您可能會問為什么會觸發兩次建議。 好吧,僅僅因為@annotation(dataTrackEnabled)捕獲了方法call()和方法execution()切入點。 因此,讓我們將匹配限制為僅處決。

完整的解決方案如下所示(不要忘記注釋的RUNTIME保留):

package com.carrot.personal.aspects;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface DataTrackEnabled {
  String dataClass();
  String dataName();
  String instance();
}
package com.carrot.personal.app;

public class DataTrackHelper {
  public void recordInstanceCount(String dataClass, String dataName, String instance) {
    System.out.println("Recording: dataClass = " + dataClass + ", dataName = " + dataName + ", instance = " + instance);
  }
}
package com.carrot.personal.app;

import com.carrot.personal.aspects.DataTrackEnabled;

import java.util.HashMap;
import java.util.Map;

public class Application {
  public static void main(String[] args) {
    System.out.println(new Application().fetchUser());
  }

  @DataTrackEnabled(dataClass = "Hey", dataName = "There", instance = "How are you?")
  public Map<String, String> fetchUser() {
    Map<String, String> returnable = new HashMap<>();
    returnable.put("firstName", "carrot");
    returnable.put("lastName", "radish");
    return returnable;
  }
}
package com.carrot.personal.aspects;

import com.carrot.personal.app.DataTrackHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class DataTrackAspect {
  @Around("@annotation(dataTrackEnabled) && execution(* *(..))")
  public Object performAspect(ProceedingJoinPoint joinPoint, DataTrackEnabled dataTrackEnabled) throws Throwable {
    System.out.println(joinPoint);
    Object result = joinPoint.proceed();
    DataTrackHelper dataTrackHelper = new DataTrackHelper();
    dataTrackHelper.recordInstanceCount(dataTrackEnabled.dataClass(), dataTrackEnabled.dataName(), dataTrackEnabled.instance());
    return result;
  }
}

我添加了更多日志 output,所以讓我們再次運行應用程序:

execution(Map com.carrot.personal.app.Application.fetchUser())
Recording: dataClass = Hey, dataName = There, instance = How are you?
{firstName=carrot, lastName=radish}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM