MapStruct 未注入到 Kotlin 项目中

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

我正在尝试按照一些在线示例使用 Spring-Boot 使用当前的 Kotlin、MapStruct 和 Java 创建一个项目,因为我是 MapStruct 的新手,但是我无法将映射器注入到我的服务中。 Idea 和 Gradle(在构建任务测试中)都抱怨没有找到 bean (UnsatisfiedDependencyException)。谷歌搜索没有帮助。我错过了什么?

MWE:

build.gradle.kts

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

plugins {
    id("org.springframework.boot") version "2.7.4"
    id("io.spring.dependency-management") version "1.0.14.RELEASE"
    kotlin("jvm") version "1.7.20"
    kotlin("plugin.spring") version "1.7.20"
    kotlin("plugin.jpa") version "1.7.20"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    implementation("org.mapstruct:mapstruct:1.5.3.Final")
    annotationProcessor("org.mapstruct:mapstruct-processor:1.5.3.Final")
}

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

tasks.withType<Test> {
    useJUnitPlatform()
}

演示应用程序.kt

package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

应用程序.kt

package com.example.demo

import org.mapstruct.Mapper
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
import org.springframework.stereotype.Service
import javax.persistence.*

@Entity
@Table(name = "items")
class Item(@Id var id: Int = 0)


data class ItemDto(val id: Int)


@Repository
interface ItemRepo : JpaRepository<Item, Int>


@Mapper(componentModel = "spring")
interface ItemMapper {
    fun entToDto(item: Item) : ItemDto
    fun entsToDtos(items: List<Item>) : List<ItemDto>
    fun dtoToEnt(itemDto: ItemDto) : Item
}

@Service
class Srvc(private val itemMapper: ItemMapper, // XXX: no bean found for this one
           private val repo: ItemRepo)
{
    fun items() = itemMapper.entsToDtos(repo.findAll())
}

// controller skipped
spring spring-boot kotlin mapstruct
1个回答
3
投票

Kapt 处于维护模式!请参阅示例:https://github.com/mapstruct/mapstruct-examples/tree/main/mapstruct-kotlin

plugin {
    // ...
    kotlin("kapt")
    // ...
}
dependencies {
    // ...
    kapt("org.mapstruct:mapstruct-processor:$version")
    implementation("org.mapstruct:mapstruct:$version")
    // ...
}

编辑(由 mpts.cz 编写 - 对于未来的我或任何像我一样刚接触 Mapstruct 和/或 Gradle 的人):

  1. 使用插件
    kotlin("kapt")
  2. 更换
    annotationProcessor("org.mapstruct:mapstruct-processor:$version")
    kapt("org.mapstruct:mapstruct-processor:$version")
  3. 将上一行放在
    implementation("org.mapstruct:mapstruct:$version")
  4. 之前

有了这些改变,一切似乎都进展顺利。谢谢努米奇!

也许是可选的,但您可能需要添加具有真实值的 keepJavacAnnotationProcessors 才能使事情正常工作。此外,您可能还需要定义一个全局映射结构配置,如下所示:

//...
kapt {
  keepJavacAnnotationProcessors = true
  arguments {
     arg("mapstruct.defaultComponentModel", "spring")
    arg("mapstruct.unmappedTargetPolicy", "IGNORE")
  }
}
//...
© www.soinside.com 2019 - 2024. All rights reserved.