将 Spring bean 注入 AspectJ 并附加切入点

问题描述 投票:0回答:1

我有一个已经使用 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 {
}

已经尝试过的代码是

  1. 在 Aspect 上使用 @Configurable 注解使切面成为 Spring 组件。不工作。
@Aspect
@Configurable
@Slf4j
public class SampleAspect {
}
  1. 使用aspectOf函数创建Aspect的bean并在其中设置存储库bean。不工作。
    @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中。

spring-boot aop aspectj spring-aop
1个回答
0
投票

将您想要的 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。

© www.soinside.com 2019 - 2024. All rights reserved.