IntelliJ不委托Maven构建时AspectJ CTW应用运行报错问题咨询
问题成因
你遇到的NoSuchMethodError提示缺少aspectOf()方法,根本原因是编译环节冲突:
- 带
@Aspect注解的类需要AspectJ编译器(Ajc)编译时自动生成aspectOf()、hasAspect()这类切面专属方法,普通JDK的javac编译器不会生成这些方法。 - IntelliJ默认优先使用自带的javac编译代码,你修改切面代码后第一次执行
maven clean install时,若IDE在你启动应用前已经提前编译了切面类,生成的class文件就没有aspectOf()方法,直接运行就会报错。 - 第一次运行报错停止后,你再次执行
maven clean install,这时aspectj-maven-plugin会覆盖IDE之前编译的class文件,用Ajc重新编译切面生成对应的方法,第二次运行就正常了。
不委托Maven的解决方案
下面三个方案任选其一即可:
方案1:将IDE默认编译器改为Ajc
让IntelliJ编译时也用AspectJ编译器,从根源避免编译结果不一致:
- 打开
File → Settings → Build, Execution, Deployment → Compiler → Java Compiler - 将
Use compiler选项从javac改为Ajc - 在
Path to aspectjtools.jar处选择你本地Maven仓库中对应版本的aspectjtools-1.9.7.jar文件 - 勾选
Delegate to Javac when no aspects in module path,普通类还是用javac编译,提升速度 - 保存配置后重新编译项目即可
方案2:修改应用启动前的执行步骤
在应用启动前强制执行Maven的编译逻辑,保证用的是aspectj-maven-plugin编译后的class:
- 打开你的Spring Boot应用对应的
Run/Debug Configurations配置 - 找到
Before launch栏,删掉默认的Build步骤 - 点击
+号选择Run Maven Goal,输入命令compile后保存 - 之后每次启动应用前都会自动执行Maven编译,不需要手动跑两次install
方案3:改用Spring AOP实现(无编译依赖)
如果你不需要用到AspectJ专属的call切点,只需要方法执行拦截,可以切换为Spring AOP实现,完全不需要AspectJ编译环节:
- 删掉pom.xml里的
aspectjrt、aspectjweaver依赖和aspectj-maven-plugin插件配置 - 给
GetSthAspect类上加@Component注解,交给Spring容器管理 - 将切点表达式从
call(* Ent.getSth())改为execution(* Ent.getSth(..))即可
注意:如果需要保留call切点的话不要选这个方案,Spring AOP不支持call类切点。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

