WebFlux 和 Kotlin 在多模块应用程序中使用 ReactiveCrudRepository

WebFlux and Kotlin use ReactiveCrudRepository in multimodule application

我有一个使用 Kotlin 和 WebFlux 的 SpringBoot 应用程序示例。我将整个应用程序分成模块(正如我从 asp.net 习惯的那样)。

模块:

我现在的问题是如何正确使用 ReactiveCrudRepository<> 和一般的存储库。我在数据模块中配置 class 以启用 R2dbcRepositories。

@Configuration
@EnableR2dbcRepositories("me.janam.data")
open class RepositoriesConfiguration {
}

现在,如果我创建 table 和存储库

interface IPersonRepository: ReactiveCrudRepository<PersonTable, Long> {
    @Query("SELECT * FROM person.person limit 1")
    fun getOne(): Mono<PersonTable>
}

并尝试在业务模块中使用它我遇到了错误

Cannot access 'org.springframework.data.repository.reactive.ReactiveCrudRepository' which is a supertype of 'me.janam.data.features.person.repositories.IPersonRepository'. Check your module classpath for missing or conflicting dependencies

当然如果我加上

implementation("org.springframework.data:spring-data-commons:2.4.6")

进入我的业务模块一切正常。但不知何故,这对我来说感觉很奇怪。这是正确的方法吗?

也不是我的主要问题的一部分,但这是完整的配置,我想听听一些关于它的意见,因为我主要是 asp.net 开发人员。谢谢

root - settings.gradle.kts:

rootProject.name = "springboot-example"
include(":api")
include(":business")
include(":data")
include(":core")

root - gradle.properties:

kotlin.code.style=official
kotlin_version=1.4.31
kotlinx_coroutines_reactor_version=1.4.3

r2dbc_postgresql_version=0.8.7.RELEASE
postgresql_version=42.2.19

spring_context_version=5.3.5

root - build.gradle.kts:

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

plugins {
    kotlin("jvm") version "1.4.31"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

subprojects {
    apply(plugin = "io.spring.dependency-management" )

    dependencyManagement {
        
    }
}

group = "me.janam"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    //implementation("org.springframework:spring-context:5.3.5")

    testImplementation(kotlin("test-junit5"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "13"
}

核心 - build.gradle.kts:

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

plugins {
    kotlin("jvm")
}

group = "me.janam"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test-junit5"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "13"
}

数据 - build.gradle.kts:

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

val kotlinx_coroutines_reactor_version: String by project
val r2dbc_postgresql_version: String by project
val postgresql_version: String by project
val spring_context_version: String by project

plugins {
    kotlin("jvm")
}

group = "me.janam"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(project(":core"))

    implementation("org.springframework:spring-context:$spring_context_version")

    implementation("org.springframework.boot:spring-boot-starter-data-r2dbc:2.4.4")
    runtimeOnly("io.r2dbc:r2dbc-postgresql:$r2dbc_postgresql_version")
    runtimeOnly("org.postgresql:postgresql:$postgresql_version")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")

    testImplementation(kotlin("test-junit5"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "13"
}

业务 - build.gradle.kts:

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

val kotlinx_coroutines_reactor_version: String by project
val spring_context_version: String by project

plugins {
    kotlin("jvm")
}

group = "me.janam"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    implementation(project(":core"))
    implementation(project(":data"))

    implementation("org.springframework:spring-context:$spring_context_version")

    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")

    implementation("org.springframework.data:spring-data-commons:2.4.6") //TODO

    testImplementation(kotlin("test-junit5"))
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "13"
}

api - build.gradle.kts:

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

plugins {
    id("org.springframework.boot") version "2.4.4"
    // Přesunuto do rootu
    id("io.spring.dependency-management")
    kotlin("jvm")
    kotlin("plugin.spring") version "1.4.31"
}

group = "me.janam"
version = "1.0-SNAPSHOT"
//java.sourceCompatibility = JavaVersion.VERSION_13

repositories {
    mavenCentral()
}

dependencies {
    implementation(project(":core"))
    implementation(project(":business"))

    //implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
    implementation("org.springframework.boot:spring-boot-starter-rsocket")
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
    //runtimeOnly("io.r2dbc:r2dbc-postgresql")
    //runtimeOnly("org.postgresql:postgresql")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("io.projectreactor:reactor-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "13"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

为每个子项目添加相同的依赖集可能感觉很奇怪,但这样做完全没问题。为了在给定的子项目中使用给定的依赖项,您必须将其指定为该子项目的依赖项。

但是,有比实际将导入语句复制粘贴到每个构建文件更简洁的方法来完成此操作。我建议在根 build.gradle.kts 中指定一个 subprojects 部分,并将共享和公共依赖项放在那里:

subprojects {
    dependencies {
        // Put items here that are used in all/most subprojects:
        implementation("org.springframework:spring-context:$spring_context_version")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinx_coroutines_reactor_version")

        // You can put this import here or just keep it in the build files
        // for subprojects where it will actually get used
        implementation("org.springframework.data:spring-data-commons:2.4.6")

        testImplementation(kotlin("test-junit5"))
        testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
    }
}

您仍然需要在每个子构建文件中指定每个其他子项目依赖于 implementation(project(":core")) 类型语句,但上面的 dependencies 块负责使指定的库可访问在所有子项目中。