在克隆项目之前浏览您的项目时,我得到了一些快速的第一印象:
- 您不应该在编译时编织场景中同时使用 Lombok + 本机 AspectJ,请在此处查看我的答案。
- 可能的解决方法是多阶段编译,即首先使用 Java + Lombok,然后使用 AspectJ 进行编译后编织,请参阅我的答案here。或者,
delombok
为了首先生成源代码,将 Lombok 注释扩展为等效源代码,然后使用 AspectJ 编译生成的源代码。
- 再看一遍,您的示例方面模块似乎没有使用任何 Lombok,因此您不需要该依赖项。但可能你真正的项目确实如此,因此我在上面的评论。
- 当然,您可以按照您的建议使用编译时编织来编织您的方面。但是,在这种情况下,您需要正确配置 AspectJ Maven 插件,而您没有这样做。除了主应用程序之外,您还需要在 Spring Boot 模块中告诉它在哪里可以找到方面库以及要编织哪些依赖项。您是否阅读过插件文档,例如章节Weaving classes in jars、Using aspect librarys和Multi-module use of AspectJ?我也已经在这里回答了很多相关的问题。
- 但实际上,将方面编织到 Spring 应用程序中的首选方法是使用加载时编织 (LTW),如Spring 手册中所述。这应该更容易配置,并且您不需要任何 AspectJ Maven 插件,并且在编译期间也可能不会有任何 Lombok 问题。
从您的示例项目和您的 AspectJ Maven 配置中没有任何aspectLibraries
和weaveDependencies
部分来看,您根本没有费心阅读任何文档,这让我想知道您在一个月内尝试使其工作的过程中做了什么。
我想发表评论,解释为什么要使用 CTW 而不是 LTW。我能想到的唯一原因是,除了您的本机方面之外,您还希望在您的 Spring 应用程序中使用 Spring AOP 方面。但是如果激活原生 AspectJ LTW,就不能再同时使用 Spring AOP。如果这不是问题,我推荐 LTW,因为它在 Spring 中有很好的文档记录和测试。CTW 也没有问题,但在您的 POM 中更难理解和管理。
更新:好的,我不想再等待您使用 CTW 的理由,只是决定向您展示 LTW 解决方案。我所做的是:
- 从 Spring 项目中删除 AspectJ Maven 插件和 AspectJ 工具
- 添加
src/main/resources/org/aspectj/aop.xml
,配置它以使用您的方面并定位您的基本包+子包
- 修复切入点以也使用您的基础包 + 子包,因为在您的基础包中没有类。这是一个典型的初学者错误。您需要使用
execution(* com.ak..*(..))
with ..
,而不仅仅是com.ak.*
.
我使用的非必需化妆品是:
- 从 Spring Boot 应用程序的 main 方法调用
context.getBean(TestController.class).mainRequest()
,以便自动产生某些方面的输出,以避免不得不使用curl
Web 浏览器来调用本地 URL。
- 通过 try-with-resources 将 Spring 应用程序用作可自动关闭的应用程序,以便在创建所需的日志输出后关闭应用程序。
- 更改方面以同时记录连接点,以便在日志中查看它实际拦截的方法。否则所有日志行看起来都一样,这不是很有帮助。
- 用于
try-finally
确保在发生异常时也会记录执行原始方法后的日志消息。
差异看起来像这样(我希望你能阅读差异):
diff --git a/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java b/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java
--- a/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java (revision Staged)
+++ b/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java (date 1626233247623)
@@ -7,14 +7,14 @@
@Aspect
public class MethodLogAspect {
- @Around("@annotation( MethodLog) && (execution(* com.ak.*(..)))")
+ @Around("@annotation(MethodLog) && execution(* com.ak..*(..))")
public Object wrap(final ProceedingJoinPoint joinPoint) throws Throwable {
- System.out.println("***Aspect invoked before calling method***");
-
- final Object obj = joinPoint.proceed();
-
- System.out.println("***Aspect invoked after calling method***");
-
- return obj;
+ System.out.println("[BEFORE] " + joinPoint);
+ try {
+ return joinPoint.proceed();
+ }
+ finally {
+ System.out.println("[AFTER] " + joinPoint);
+ }
}
}
diff --git a/src/main/java/com/ak/ParentprojectSpringbootApplication.java b/src/main/java/com/ak/ParentprojectSpringbootApplication.java
--- a/src/main/java/com/ak/ParentprojectSpringbootApplication.java (revision Staged)
+++ b/src/main/java/com/ak/ParentprojectSpringbootApplication.java (date 1626233555873)
@@ -1,14 +1,17 @@
package com.ak;
+import com.ak.controller.TestController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackages = { "com.ak.*" })
-//@SpringBootApplication
public class ParentprojectSpringbootApplication {
public static void main(String[] args) {
- SpringApplication.run(ParentprojectSpringbootApplication.class, args);
+ try (ConfigurableApplicationContext context = SpringApplication.run(ParentprojectSpringbootApplication.class, args)) {
+ context.getBean(TestController.class).mainRequest();
+ }
}
}
diff --git a/parentproject-springboot/pom.xml b/parentproject-springboot/pom.xml
--- a/parentproject-springboot/pom.xml (revision Staged)
+++ b/parentproject-springboot/pom.xml (date 1626232421474)
@@ -71,13 +71,6 @@
<version>1.9.6</version>
</dependency>
- <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools -->
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjtools</artifactId>
- <version>1.9.6</version>
- </dependency>
-
<dependency>
<groupId>com.ak.aspect</groupId>
<artifactId>aspect-test-project</artifactId>
@@ -100,24 +93,6 @@
</configuration>
</plugin>
- <plugin>
- <groupId>com.nickwongdev</groupId>
- <artifactId>aspectj-maven-plugin</artifactId>
- <version>1.12.6</version>
- <configuration>
- <source>11</source>
- <target>11</target>
- <complianceLevel>11</complianceLevel>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- <goal>test-compile</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
为方便起见,以下是完整更改的文件:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.ak</groupId>
<artifactId>parentproject-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>parentproject-springboot</name>
<description>Test project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ak.dependency</groupId>
<artifactId>dependencyprojet</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- aspectj runtime dependency -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>com.ak.aspect</groupId>
<artifactId>aspect-test-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-verbose -showWeaveInfo">
<!-- only weave classes in our application-specific packages -->
<include within="com.ak..*"/>
</weaver>
<aspects>
<aspect name="com.ak.aspect.MethodLogAspect"/>
</aspects>
</aspectj>
package com.ak.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MethodLogAspect {
@Around("@annotation(MethodLog) && execution(* com.ak..*(..))")
public Object wrap(final ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("[BEFORE] " + joinPoint);
try {
return joinPoint.proceed();
}
finally {
System.out.println("[AFTER] " + joinPoint);
}
}
}
package com.ak;
import com.ak.controller.TestController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackages = { "com.ak.*" })
public class ParentprojectSpringbootApplication {
public static void main(String[] args) {
try (ConfigurableApplicationContext context = SpringApplication.run(ParentprojectSpringbootApplication.class, args)) {
context.getBean(TestController.class).mainRequest();
}
}
}
现在您只需确保将 JVM 参数添加-javaagent:/path/to/aspectjweaver-1.9.6.jar
到您的 Java 命令行以激活本机 AspectJ LTW。有关如何在 Spring 中配置 LTW 的更多详细信息,请阅读 Spring 手册中的Using AspectJ with Spring Applications部分。
控制台日志应如下所示:
[AppClassLoader@3764951d] info AspectJ Weaver Version 1.9.6 built on Tuesday Jul 21, 2020 at 13:30:08 PDT
[AppClassLoader@3764951d] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@3764951d
[AppClassLoader@3764951d] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_SpringCTWMultiModule_68040124/parentproject-springboot/target/classes/org/aspectj/aop.xml
[AppClassLoader@3764951d] info register aspect com.ak.aspect.MethodLogAspect
[AppClassLoader@3764951d] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
[RestartClassLoader@1f385e10] info AspectJ Weaver Version 1.9.6 built on Tuesday Jul 21, 2020 at 13:30:08 PDT
[RestartClassLoader@1f385e10] info register classloader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1f385e10
[RestartClassLoader@1f385e10] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_SpringCTWMultiModule_68040124/parentproject-springboot/target/classes/org/aspectj/aop.xml
[RestartClassLoader@1f385e10] info register aspect com.ak.aspect.MethodLogAspect
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.2)
(...)
[RestartClassLoader@1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.AccountInfo com.ak.service.TestService.incomingRequest())' in Type 'com.ak.service.TestService' (TestService.java:20) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java)
[RestartClassLoader@1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.AccountInfo com.ak.dependency.Route.accountInfo())' in Type 'com.ak.dependency.Route' (Route.java:12) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java)
[RestartClassLoader@1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.BalanceInfo com.ak.dependency.Pipeline.balanceInfo())' in Type 'com.ak.dependency.Pipeline' (Pipeline.java:11) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java)
(...)
Controller
[BEFORE] execution(AccountInfo com.ak.service.TestService.incomingRequest())
[BEFORE] execution(AccountInfo com.ak.dependency.Route.accountInfo())
[BEFORE] execution(BalanceInfo com.ak.dependency.Pipeline.balanceInfo())
[AFTER] execution(BalanceInfo com.ak.dependency.Pipeline.balanceInfo())
[AFTER] execution(AccountInfo com.ak.dependency.Route.accountInfo())
[AFTER] execution(AccountInfo com.ak.service.TestService.incomingRequest())
(...)