AspectJ无法增强JDK类(如java.util.ArrayList),求解决方法
如何用AspectJ增强JDK核心类(以ArrayList为例)
你遇到的问题核心是:AspectJ默认的编译时织入(CTW)只能处理项目自身编译的类,无法直接增强JDK核心类,这类系统类需要用**加载时织入(Load-Time Weaving, LTW)**来实现增强。下面是具体的解决步骤:
1. 统一项目编译版本并修正pom.xml
你的pom.xml中存在版本不一致问题(properties里是JDK17,但AspectJ插件配置的是11),先统一版本,同时补充LTW相关配置:
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <aspectj.version>1.9.21</aspectj.version> </properties> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> <build> <plugins> <!-- 修正AspectJ插件的版本配置,和项目JDK版本一致 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.15.0</version> <configuration> <complianceLevel>17</complianceLevel> <source>17</source> <target>17</target> <showWeaveInfo>true</showWeaveInfo> <verbose>true</verbose> <Xlint>ignore</Xlint> <encoding>UTF-8</encoding> </configuration> <executions> <execution> <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> </dependencies> </plugin> <!-- 配置exec插件,方便通过maven启动并加载织入器 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>Main</mainClass> <!-- 指定javaagent,加载AspectJ织入器 --> <arguments> <argument>-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar</argument> </arguments> </configuration> </plugin> </plugins> </build>
2. 创建LTW配置文件META-INF/aop.xml
在项目的src/main/resources目录下创建META-INF/aop.xml,这个文件告诉AspectJ织入器要激活哪些切面,以及要增强的目标类:
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd"> <aspectj> <!-- 指定要启用的切面类 --> <aspects> <aspect name="MyAspect"/> </aspects> <!-- 指定要织入的目标类范围,这里是JDK的ArrayList --> <weaver options="-verbose -showWeaveInfo"> <include within="java.util.ArrayList"/> <!-- 如果需要增强更多JDK类,可以继续添加include --> </weaver> </aspectj>
3. 启动项目的两种方式
方式一:通过IntelliJ IDEA直接运行
在Run/Debug Configurations中,为Main类添加VM参数:
-javaagent:~/.m2/repository/org/aspectj/aspectjweaver/1.9.21/aspectjweaver-1.9.21.jar
(注意替换成你本地maven仓库中aspectjweaver.jar的实际路径)
方式二:通过Maven命令运行
在项目根目录执行:
mvn clean compile exec:java
4. 验证效果
运行Main类后,控制台会输出:
afterArrayListAspect added afterArrayListAspect
这说明add和get方法都被成功增强。
关键说明
- 加载时织入(LTW)是在JVM加载类的时候,动态将切面逻辑织入到目标类中,因此可以处理JDK核心类这类不在项目编译范围内的类。
- 确保
aop.xml的路径和内容正确,它是LTW生效的核心配置文件。 - 如果切面没有生效,检查javaagent路径是否正确,或者查看控制台的织入日志(通过
-verbose参数开启),确认ArrayList类是否被织入。
内容的提问来源于stack exchange,提问作者Adolis Pali
相关产品推荐
相关产品推荐

