AspectJ编译时织入启动异常:ajc$perSingletonInstance为空及构造方法缺失
解决AspectJ编译时织入的NoAspectBoundException异常
问题根源
你的切面类EnsureFromMonolith使用@RequiredArgsConstructor生成带参构造,没有无参构造。在AspectJ编译时织入(CTW)模式下,AspectJ默认会尝试用无参构造实例化切面;同时你用@Component希望Spring管理切面,两种实例化机制冲突,导致启动时抛出异常。
解决方案
方案1:给切面添加无参构造方法(最简方案)
通过Lombok同时生成带参和无参构造,让AspectJ能实例化切面,Spring再通过带参构造注入真实依赖:
@Aspect @Component @RequiredArgsConstructor @NoArgsConstructor(force = true) // force=true为final字段赋默认值,避免编译报错 public class EnsureFromMonolith { private final Dependency1 dep1; private final Dependency2 dep2; @Around("execution(* com.xyz..*(..))") public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable { // 你的环绕通知逻辑 return joinPoint.proceed(); } }
方案2:配置AspectJ插件让Spring管理切面实例
修改pom.xml中的AspectJ插件配置,引入Spring的AspectJ支持,让Spring负责切面的实例化和依赖注入:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <!-- 适配Java21的版本 --> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <source>${java.version}</source> <target>${java.version}</target> <complianceLevel>${java.version}</complianceLevel> <aspectLibraries> <aspectLibrary> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </aspectLibrary> </aspectLibraries> <weaveDirectories> <weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory> </weaveDirectories> <Xlint>ignore</Xlint> </configuration> </execution> </executions> </plugin>
同时确保项目引入spring-aspects依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency>
方案3:调整编译流程,兼容Lombok与AspectJ
让AspectJ插件直接处理Lombok生成的构造方法,调整插件配置顺序:
<!-- Maven编译插件:编译到unwoven-classes并处理Lombok --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven-compiler.version}</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <outputDirectory>${project.build.directory}/unwoven-classes</outputDirectory> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> <!-- AspectJ插件:处理Lombok并织入切面 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok-aspectj</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <source>${java.version}</source> <target>${java.version}</target> <complianceLevel>${java.version}</complianceLevel> <weaveDirectories> <weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory> </weaveDirectories> <proc>none</proc> <!-- 禁用javac注解处理,由AspectJ处理Lombok --> <Xlint>ignore</Xlint> </configuration> </execution> </executions> </plugin>
验证步骤
- 执行
mvn clean compile确认编译无报错 - 检查
target/classes下的切面类字节码,确认构造方法符合预期 - 启动应用,验证异常是否消失
- 测试目标方法,确认切面环绕通知逻辑生效
内容的提问来源于stack exchange,提问作者Surabhya Aryal
相关产品推荐
相关产品推荐

