多模块 Kotlin 项目中的 Freefair

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

我在 Kotlin-Gradle 多模块项目中使用

io.freefair.aspectj.post-compile-weaving
插件来启用我的 springboot 应用程序中的各个方面。

当我尝试在一个简单的项目中使用该插件时,它工作得非常好,然后当我将项目拆分为多模块时,它开始不再识别各个方面了

这是我在 github 上创建的 MCVE

所以我基本上设置了根项目 gradle 文件:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "3.1.5"
    id("io.spring.dependency-management") version "1.1.3"
    id("io.freefair.aspectj.post-compile-weaving") version "6.6.3"
    kotlin("jvm") version "1.8.22"
    kotlin("plugin.spring") version "1.8.22"
}

group = "com.voiddev"

allprojects {
    apply(plugin = "org.jetbrains.kotlin.jvm")
    apply(plugin = "kotlin-spring")
    apply(plugin = "io.spring.dependency-management")
    apply(plugin = "org.springframework.boot")
    apply(plugin = "io.freefair.aspectj.post-compile-weaving")

    version = "0.0.1-SNAPSHOT"
    java {
        sourceCompatibility = JavaVersion.VERSION_17
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-web")
        implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        testImplementation("org.springframework.boot:spring-boot-starter-test")

        implementation("org.aspectj:aspectjrt:1.9.19")
    }

    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs += "-Xjsr305=strict"
            jvmTarget = "17"
        }
    }

    tasks.withType<Test> {
        useJUnitPlatform()
    }
}

然后我所做的就是尝试使用“服务器”模块中“公共”模块中定义的方面。 我确实导入了服务器模块中的通用模块,因为我能够访问

common
模块中定义的类。 这是我的服务器 gradle 文件:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "3.1.5"
    id("io.spring.dependency-management") version "1.1.3"
    id("io.freefair.aspectj.post-compile-weaving") version "6.6.3"
    kotlin("jvm") version "1.8.22"
    kotlin("plugin.spring") version "1.8.22"
}

group = "com.voiddev"

dependencies {
    implementation(project(":common"))
}

tasks {
    bootJar {
        archiveBaseName.set(rootProject.name)
    }
}

然而这些方面却被忽视了

kotlin gradle aspectj freefair-aspectj
1个回答
0
投票

实际上,我想知道为什么你要使用原生 AspectJ,因为你将切面应用于 Spring 服务。即,常规的“AOP lite”,称为 Spring AOP,它随 Spring 一起提供,就足够了。为此,您不需要任何额外的构建插件。

无论如何,回答你的问题:你的模块

common
是一个方面库。为了使 AspectJ 编译器能够识别它,您应该将它放在切面路径上,而不是放在常规类路径上。在 Freefair 中,如此处记录,这样做是这样的:

dependencies {
    aspect(project(":common"))
}

然后,就可以了。鉴于此服务器应用程序,...

@SpringBootApplication
class ServerApplication

fun main(args: Array<String>) {
  runApplication<ServerApplication>(*args).use {
    println(it.getBean(AspectService::class.java).randomFunction())
  }
}

...控制台日志将是:

MetricAspect: $Proxy57
MetricAspect: $Proxy57
Hello Aspect

但是当然,使用本机 AspectJ 时您的切入点太通用了。它将匹配两次,一次匹配

call
,一次匹配
execution
连接点。在 Spring AOP 中不会发生这种情况,因为后者只知道
execution
。你可以像这样修复它:

@After("@annotation(metricAnnotation) && execution(* *(..))")

控制台日志更改为:

MetricAspect: $Proxy57
Hello Aspect

您可能还想考虑将两个模块中的 Freefair 插件从 6.6.3 升级到 8.4:

id("io.freefair.aspectj.post-compile-weaving") version "8.4"
© www.soinside.com 2019 - 2024. All rights reserved.