Kotlin 语言参考文档 中文版 Help

在 Kotlin 项目中使用注解处理器

注解处理器在编译期间分析你的源代码, 以生成样板代码, 验证用法, 或生成其他构件(artifact). Kotlin 支持两种方式来使用注解处理器:

  • kapt 编译器 plugin, 工作方式是, 从 Kotlin 源代码生成桩(stub)文件, 然后在这些桩(stub)上运行 Java 注解处理器. 这个额外的桩(stub)生成步骤会使构建时间变慢, 同时意味着 kapt 无法理解 Kotlin 特有的构造, 例如 扩展函数null 安全.

    kapt 同时支持 Maven 和 Gradle. 推荐用于所有的 Maven 项目, 以及那些使用尚未采用 KSP 的处理器库的 Gradle 项目, 例如 MapStruct.

  • KSP 框架, 通过 Kotlin 优先的 API 直接读取 Kotlin 源代码, 不需要生成桩. 它能够原生的理解 Kotlin 特有的功能, 构建速度比 kapt 更快.

    目前, KSP 只对 Gradle 提供官方支持. 推荐用于编写自己的处理器, 以及与支持 KSP 的库 (例如 Dagger) 配合使用.

配合使用 kapt 与 Java 注解处理器

kapt 让你能够在 Kotlin 项目中使用既有的 Java 注解处理器, 不需要对处理器本身做任何修改.

下面的示例演示如何使用 MapStruct 注解处理器. MapStruct 会在编译期间生成 Java Bean 之间类型安全的 mapper 实现.

  1. 在你的构建文件中, 应用 kapt plugin, 并将 MapStruct 添加到 dependencies 部分:

    <properties> <kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget> <mapstruct.version>1.6.3</mapstruct.version> </properties> <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> </dependencies> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <extensions>true</extensions> <executions> <execution> <id>kapt</id> <goals> <goal>kapt</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/main/kotlin</sourceDir> <sourceDir>src/main/java</sourceDir> </sourceDirs> <aptMode>stubs</aptMode> <annotationProcessorPaths> <annotationProcessorPath> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </annotationProcessorPath> </annotationProcessorPaths> </configuration> </execution> </executions> </plugin>
    • 将来自 kotlin-maven-pluginkapt goal 的执行, 添加到 compile 执行 之前.

    • 使用 aptMode 选项, 配置 注解处理级别.

    plugins { kotlin("kapt") version "2.4.0" } dependencies { implementation("org.mapstruct:mapstruct:1.6.3") kapt("org.mapstruct:mapstruct-processor:1.6.3") }
    plugins { id "org.jetbrains.kotlin.kapt" version "2.4.0" } dependencies { implementation "org.mapstruct:mapstruct:1.6.3" kapt "org.mapstruct:mapstruct-processor:1.6.3" }
  2. 定义你的数据类和 mapper 接口:

    import org.mapstruct.Mapper import org.mapstruct.factory.Mappers data class UserDto(val id: Long, val firstName: String, val lastName: String) data class UserEntity(val id: Long, val firstName: String, val lastName: String) @Mapper interface UserMapper { fun toDto(entity: UserEntity): UserDto fun toEntity(dto: UserDto): UserEntity companion object : UserMapper by Mappers.getMapper(UserMapper::class.java) }
  3. 构建项目. MapStruct 会在生成的源代码目录中生成 UserMapperImpl 类. 使用 UserMapper 同伴对象来调用生成的实现:

    fun main() { val entity = UserEntity(id = 1L, firstName = "John", lastName = "Doe") val dto = UserMapper.toDto(entity) println(dto) // 输出结果为: UserDto(id=1, firstName=John, lastName=Doe) }

在 Gradle 项目中使用 KSP

使用 KSP, 你可以在 Gradle 项目中使用既有的注解处理器, 也可以创建自己的处理器, 根据源代码中的注解来生成代码.

配合使用 KSP 与 Java 注解处理器

对于 Gradle 项目, 请将 KSP 与兼容的注解处理器配合使用. KSP 比 kapt 更快, 并且能够原生理解 Kotlin 特有的功能. 请查看 已支持 KSP 的库列表.

下面的示例演示如何使用 Dagger, 这是一个编译期间依赖注入框架, 它根据依赖图生成连接代码.

  1. 在你的 build.gradle(.kts) 文件中, 应用 KSP plugin, 并将 Dagger 添加到 dependencies 代码块:

    // build.gradle.kts plugins { kotlin("jvm") version "2.4.0" id("com.google.devtools.ksp") version "2.3.9" } dependencies { implementation("com.google.dagger:dagger:2.59.2") ksp("com.google.dagger:dagger-compiler:2.59.2") }
    // build.gradle plugins { id 'org.jetbrains.kotlin.jvm' version '2.4.0' id 'com.google.devtools.ksp' version '2.3.9' } dependencies { implementation 'com.google.dagger:dagger:2.59.2' ksp 'com.google.dagger:dagger-compiler:2.59.2' }

  2. 使用 Dagger 注解, 对你的 Kotlin 类进行标注:

    import javax.inject.Inject import javax.inject.Singleton import dagger.Component import dagger.Module import dagger.Provides @Singleton class UserRepository @Inject constructor() { fun getUser(): String = "John Doe" } @Module class AppModule { @Provides @Singleton fun provideUserRepository(): UserRepository = UserRepository() } @Singleton @Component(modules = [AppModule::class]) interface AppComponent { fun userRepository(): UserRepository }
  3. 构建项目. Dagger 会在 build/generated/ksp 目录中生成实现类, 例如 DaggerAppComponent. 在你的代码中使用生成的类:

    fun main() { val appComponent = DaggerAppComponent.create() val userRepository = appComponent.userRepository() println("User: ${userRepository.getUser()}") // 输出结果为: User: John Doe }

关于 Dagger 对 KSP 的支持, 详情请参见它的 文档.

创建你自己的注解处理器

你可以使用 KSP API 编写自己的注解处理器, 在编译期间生成代码. 一个新的处理器需要 3 个模块:

  • 一个 annotation 模块, 用于声明自定义注解.

  • 一个 processor 模块, 用于实现 SymbolProcessorSymbolProcessorProvider 工厂类. SymbolProcessor 包含主逻辑, SymbolProcessorProvider 创建处理器, 并在 META-INF/services/ 路径下注册 provider.

  • 一个 app 模块, 用于应用 KSP plugin, 依赖于处理器, 并使用注解.

关于完整的逐步说明, 请参见 KSP 快速入门.

下一步做什么?

2026/07/24