我有一个已经使用 Spring AOP 的 Spring Boot 项目。对于新功能,需要使用
cflow
切入点,因此必须集成 AspectJ。
我成功地将 Compile Time Weave 方面编入我的项目中,并且可以看到该方面正在运行。我知道当项目有 lombok 时应该使用加载时编织,但我设法使用以下博客来运行它。
这是 pom.xml 中用于编译时编织的插件。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<configuration>
<complianceLevel>11</complianceLevel>
<source>11</source>
<target>11</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sources/>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<forceAjcCompile>true</forceAjcCompile>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>process-test-classes</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sources/>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<forceAjcCompile>true</forceAjcCompile>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/test-classes</weaveDirectory>
</weaveDirectories>
</configuration>
</execution>
</executions>
</plugin>
aspect的作用是通过截获的jointpoint来查询数据库。为此,我尝试将带有
@Repository
注释的 Spring bean 注入到方面中。由于方面不是 spring 组件,我无法在方面类中 @Autowire 存储库。
存储库类
@Repository
public interface SampleRepository extends JpaRepository<Sample, String> {
}
方面类
@Aspect
@Slf4j
public class SampleAspect {
}
已经尝试过的代码是
@Aspect
@Configurable
@Slf4j
public class SampleAspect {
}
@Bean
public SampleAspect sampleAspect(){
SampleAspect sampleAspect = Aspects.aspectOf(SampleAspect.class);
sampleAspect.setRepository(sampleRepository);
return sampleAspect;
}
在上述两个步骤中,我都收到错误 unsupported jointpoint cflow。
Initialization of bean failed; nested exception is org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException: contains unsupported pointcut primitive 'cflow'
我在这里遗漏了什么吗?我需要将一个bean注入普通的旧aspectj中。
将您想要的 POJO 类
@Autowire
依赖为 @Configurable
是正确的,如果该类恰好是本机 AspectJ 方面也是正确的。然而,将本机切面设为 @Bean
或 @Component
是错误且适得其反的方法,因为这会将该切面第二次注册为 Spring AOP 切面,这也解释了 UnsupportedPointcutPrimitiveException ... cflow
问题。
这张图片中缺少的信息是,要使
@Configurable
工作,您需要类路径上 AnnotationBeanConfigurerAspect
中的 spring-aspects
。对于加载时和编译时编织场景都是如此。也就是说,您希望 POM 中有这样的内容:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
在 AspectJ Maven 插件配置中,您还需要将
spring-aspects
声明为切面库:
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
欲了解更多详情,请参阅此相关答案。
P.S.:我发现在后续阶段中在单个模块中使用 Maven 编译器和 AspectJ Maven 的方法,在相同的输出目录上工作,是有问题的,即使在你的情况下它似乎有效。我建议在模块 A 中使用 Maven 编译器和 Lombok 构建一个未编织的模块版本,然后在模块 B 中将方面编织到 A 的类中。所有其他模块应该依赖于 B 而不是中介 A。