首页 > 解决方案 > 带有 Kotlin 和 Gradle 的 Spring AOP (AspectJ) - 我无法让它工作

问题描述

我有一个 Spring Boot + Kotlin + Gradle 项目。我想为我的用例创建一个小型库。这个库应该使用 AOP 来消除我观察到的一些横切问题。

因此,我开始将这两个依赖项添加到我的 gradle 构建文件中。

build.gradle.kts

implementation("org.springframework:spring-aop:5.2.9.RELEASE")
implementation("org.springframework:spring-aspects:5.2.9.RELEASE")

由于来自互联网的一些建议,我还添加了 freefair aspectj 插件。我创建的以下方面应src/main/aspectj根据此文档放置:https ://docs.freefair.io/gradle-plugins/5.2.1/reference/#_io_freefair_aspectj

该插件通过将 aspectj 目录添加到每个源集来为项目添加 AspectJ 支持。src/main/aspectj 目录中包含的源代码将由 compileAspectj 任务使用 ajc 进行编译。

plugins {
    // ...
    id("io.freefair.aspectj") version "5.2.1"
    // ...
}

然后我开始创建我的第一个方面,它匹配每个带有注释的方法@Foozy

src/main/aspectj/FoozyAspect.kt<“特殊”源路径

@Component
@Aspect
class FoozyAspect {

    @Before("@annotation(com.client.annotation.Foozy)")
    fun doStuff() {
        LOG.info("Do Stuff")
    }

    companion object {
        private val LOG = LoggerFactory.getLogger(FoozyAspect::class.java)
    }
}

然后我创建了这个注释

src/main/kotlin/com.client.annotation/Foozy.kt

@Target(AnnotationTarget.FUNCTION)
annotation class Foozy

现在为了测试一切是否按预期工作,我创建了一个单元测试

src/test/kotlin/FoozyAspectTest.kt

@SpringBootTest
@EnableAspectJAutoProxy
internal class FoozyAspectTest {
    private val testCandidate: TestCandidate = TestCandidate()

    @Test
    fun `should work with aspect`() {
        testCandidate.doStuff()
    }
}

src/test/TestCandidate.kt

class TestCandidate {
    @Foozy
    fun doStuff(): String {
        return "stuff"
    }
}

结果

在调试模式下执行文本不会产生等待的信息日志Do Stuff,也不会在FoozyAspect.kt doStuff()方法的断点处停止线程。我不知道在这里配置什么。出于充分的理由,我有点怀疑我正在混合不同的“方法”来使其工作,或者只是错过了预配置/先决条件中的一些最后步骤。

标签: springkotlingradlespring-aop

解决方案


这看起来像是经典 Spring AOP 问题的第 347 个副本:如果您阅读手册,您会注意到 Spring AOP 仅适用于 Spring 组件,例如通过@Componentor声明@Bean

TestCandidate似乎是一个 POJO,所以 Spring 不知道它。此外,如果您将其设为组件,请确保从容器中获取一个实例,而不是仅在测试中通过构造函数调用创建一个实例。


推荐阅读