Kotlin 语言参考文档 中文版 Help

KSP 入门

在这篇指南中, 你将学习:

  • 如何向你的项目添加基于 KSP 的注解处理器.

  • 如何使用 KSP API 创建你自己的注解处理器.

  • 在哪里查找处理器生成的代码.

向你的项目添加基于 KSP 的处理器

要在你的项目中使用外部处理器, 请在 build.gradle(.kts) 文件的 plugins {} 代码块 中添加 KSP. 如果只有某个特定模块需要这个处理器, 请改为在该模块的 build.gradle(.kts) 文件中添加:

// build.gradle.kts plugins { kotlin("jvm") version "2.4.0" id("com.google.devtools.ksp") version "2.3.9" }
// build.gradle plugins { id 'org.jetbrains.kotlin.jvm' version '2.4.0' id 'com.google.devtools.ksp' version '2.3.9' }

在最顶层的 dependencies {} 代码块中, 添加你想要使用的处理器. 这个示例使用 Moshi, 其他处理器的添加方式也是一样的:

// build.gradle.kts dependencies { ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2") }
// build.gradle dependencies { ksp 'com.squareup.moshi:moshi-kotlin-codegen:1.15.2' }

创建你自己的处理器

按照以下步骤, 你将创建一个简单的注解处理器, 它会生成一个 helloWorld() 函数. 虽然在实际中用处不大, 但它演示了创建你自己的处理器和注解的基本方法.

向项目添加 KSP

创建一个新的 Kotlin 项目, 并添加 KSP plugin:

  1. 在 IntelliJ IDEA 中, 选择 File | New | Project.

  2. 在左侧列表中, 选择 Kotlin.

  3. 选择 Gradle 作为构建系统, 然后点击 Create.

    创建新项目
  4. build.gradle(.kts) 文件添加 KSP plugin:

    // build.gradle.kts plugins { kotlin("jvm") version "2.4.0" id("com.google.devtools.ksp") version "2.3.9" apply false }
    // build.gradle plugins { id 'org.jetbrains.kotlin.jvm' version '2.4.0' id 'com.google.devtools.ksp' version '2.3.9' apply false }

创建注解

在项目的根目录创建一个新模块, 并声明一个注解:

  1. 选择 File | New | Module.

  2. 在左侧列表中, 选择 Kotlin.

  3. 填写以下项目, 然后点击 create:

    • Name: annotations

    • Build system: Gradle

    创建新模块
  4. 在这个模块中, 创建 HelloWorldAnnotation.kt 文件, 并声明一个注解, 名为 HelloWorldAnnotation:

    // annotations/src/main/kotlin/com/example/annotations/HelloWorldAnnotation.kt package com.example.annotations annotation class HelloWorldAnnotation

创建并注册处理器

  1. 在项目的根目录创建另一个模块, 名为 processor.

  2. 在这个模块的 build.gradle(.kts) 文件中, 将 KSP API 和你声明的注解添加为依赖项:

    // processor/build.gradle.kts plugins { kotlin("jvm") } dependencies { implementation(project(":annotations")) implementation("com.google.devtools.ksp:symbol-processing-api:2.3.6") }
    // processor/build.gradle plugins { id 'org.jetbrains.kotlin.jvm' } dependencies { implementation project ':annotations' implementation 'com.google.devtools.ksp:symbol-processing-api:2.3.6' }
  3. processor 模块中, 创建一个新的 HelloWorldProcessor.kt 文件, 添加以下代码:

    // processor/src/main/kotlin/HelloWorldProcessor.kt class HelloWorldProcessor(val codeGenerator: CodeGenerator) : SymbolProcessor { // 1️⃣ process() 函数 override fun process(resolver: Resolver): List<KSAnnotated> { resolver .getSymbolsWithAnnotation("com.example.annotations.HelloWorldAnnotation") .filter { it.validate() } .filterIsInstance<KSFunctionDeclaration>() .forEach { it.accept(HelloWorldVisitor(), Unit) } return emptyList() } // 2️⃣ 访问器(Visitor) inner class HelloWorldVisitor : KSVisitorVoid() { override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) { createNewFileFrom(function).use { file -> file.write( """ fun helloWorld(): Unit { println("Hello world from function generated by KSP") } """.trimIndent() ) } } } // 3️⃣ createNewFileFrom() 函数 private fun createNewFileFrom(function: KSFunctionDeclaration): OutputStream { return codeGenerator.createNewFile( dependencies = createDependencyOn(function), packageName = "", fileName = "GeneratedHelloWorld" ) } // 3️⃣ createDependencyOn() 函数 private fun createDependencyOn(function: KSFunctionDeclaration): Dependencies { return Dependencies(aggregating = false, function.containingFile!!) } } // 工具函数, 用于将字符串写入 OutputStream fun OutputStream.write(string: String): Unit { this.write(string.toByteArray()) }

    添加 IDE 建议的 import 语句. 请确保从 com.google.devtools.ksp.processing 导入 ResolverDependencies 类. 或者, 将以下代码复制到 HelloWorldProcessor.kt 的顶部:

    // processor/src/main/kotlin/HelloWorldProcessor.kt import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSFunctionDeclaration import com.google.devtools.ksp.symbol.KSVisitorVoid import com.google.devtools.ksp.validate import java.io.OutputStream

    我们来逐步了解这段代码:

    • 1️⃣ process() 函数包含处理器的主逻辑. 它获取所有带有 HelloWorldAnnotation 注解的符号, 并为每个符号调用 HelloWorldVisitor.

      process() 函数返回未处理的符号列表, 以便在后续轮次中进行处理. 在这个示例中, 它安全地返回 emptyList(). 详情请参见 多轮处理.

    • 2️⃣ 处理器使用访问器(Visitor)遍历 KSP 对 Kotlin 抽象语法树 (Abstract Syntax Tree, AST) 的视图. 在 HelloWorldPocessor 类中, HelloWorldVisitor 类是访问器(Visitor). 由于 HelloWorldAnnotation 只用于函数, 因此只覆盖了 visitFunctionDeclaration().

    • 3️⃣ createNewFileFrom() 创建 KSP 生成代码的文件. createDependencyOn() 使输出的文件依赖于使用注解的源代码文件.

  4. 创建 HelloWorldProcessorProvider.kt 文件. 在这个文件中, 声明一个 HelloWorldProcessorProvider 类, 继承自 SymbolProcessorProvider:

    // processor/src/main/kotlin/HelloWorldProcessorProvider.kt import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.processing.SymbolProcessorProvider class HelloWorldProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { return HelloWorldProcessor(environment.codeGenerator) } }
  5. 注册处理器 Provider. 在 resources/META-INF/services 目录中, 创建 com.google.devtools.ksp.processing.SymbolProcessorProvider 文件, 并添加 Provider 的完全限定名称:

    ## processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider HelloWorldProcessorProvider

使用你的处理器

现在你已经准备好, 可以测试你的处理器了. 按照以下步骤创建客户端模块, 让你的处理器根据带有注解的元素生成代码:

  1. 在项目根目录创建一个模块, 名为 app.

  2. 在这个模块的 build.gradle(.kts) 文件中:

    • plugins {} 代码块中, 添加 KSP 插件.

    • dependencies {} 代码块中, 添加你的处理器和注解.

    例如:

    // app/build.gradle.kts plugins { kotlin("jvm") id("com.google.devtools.ksp") } dependencies { implementation(project(":annotations")) ksp(project(":processor")) }
    // app/build.gradle plugins { id 'com.google.devtools.ksp' } dependencies { implementation project (':annotations') ksp project (':processor') }
  3. 在项目级的 settings.gradle(.kts) 文件中, 确认所有子模块都已自动包含:

    // settings.gradle.kts include("annotations") include("app") include("processor")
    // settings.gradle include 'processor' include 'annotations' include 'app'
  4. app 模块中, 创建 Main.kt 文件, 添加以下代码:

    // app/src/main/kotlin/Main.kt import com.example.annotations.HelloWorldAnnotation @HelloWorldAnnotation fun main() { helloWorld() }

  5. 运行程序. 你会在控制台中看到 helloWorld() 函数的输出:

    Hello world from function generated by KSP

    KSP 在 GeneratedHelloWorld.kt 文件中生成代码:

    app/build/generated/ksp/main/kotlin/GeneratedHelloWorld.kt

查看项目结构

你的项目的最终文件结构应该如下所示:

. ├── app │ ├── build.gradle.kts │ └── src │ └── main │ └── kotlin │ └── Main.kt ├── annotations │ ├── build.gradle.kts │ └── src │ └── main │ └── kotlin | └── com | └── example | └── annotations | └── HelloWorldAnnotation.kt ├── processor │ ├── build.gradle.kts │ └── src │ └── main │ ├── kotlin │ │ ├── HelloWorldProcessor.kt │ │ └── HelloWorldProcessorProvider.kt │ └── resources/META-INF/services | └── com.google.devtools.ksp.processing.SymbolProcessorProvider ├── build.gradle.kts └── settings.gradle.kts

下一步做什么?

2026/08/12