rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • KSP

  • 一、KSP 是什么
    • 核心定位
    • 与 KAPT 的关键区别
  • 二、核心概念与架构
    • 1. 核心组件
    • 2. 处理流程
  • 三、核心 API 与符号模型
    • 1. 核心符号类型
    • 2. 常用 API 示例
  • 四、快速上手:开发 KSP 处理器
    • 1. 环境配置(Gradle)
    • 2. 定义注解
    • 3. 实现 SymbolProcessor
    • 4. 注册处理器(SPI)
    • 5. 实现 ProcessorProvider
    • 6. 使用处理器
  • 五、KSP 优势与适用场景
    • 核心优势
    • 适用场景
  • 六、KSP2 新特性(最新版本)
  • 七、总结

KSP

KSP(Kotlin Symbol Processing)是 Kotlin 官方推出的编译期符号处理 API,用于在编译阶段读取、分析 Kotlin 代码结构并生成新代码,是替代 KAPT、实现高效注解处理与代码生成的核心方案。

一、KSP 是什么

KSP = Kotlin Symbol Processing,是一套轻量级编译器插件 API,专门处理 Kotlin 代码的符号信息(类、函数、属性、注解、泛型等),在编译期完成代码分析与生成,不侵入运行时。

核心定位

  • 替代传统 Java Annotation Processing(AP) 与 KAPT,专为 Kotlin 设计
  • 直接操作 Kotlin 符号模型,无需解析 Java 字节码
  • 支持完整 Kotlin 特性:扩展函数、密封类、协程、声明点泛型、局部函数等
  • 核心用途:注解处理、代码生成、编译期校验、元编程

与 KAPT 的关键区别

特性KSPKAPT(Kotlin Annotation Processing Tool)
底层直接处理 Kotlin 符号先将 Kotlin 转 Java stub,再用 Java AP 处理
性能快(增量编译、无 stub 开销)慢(生成 stub、全量编译多)
Kotlin 支持原生支持所有特性仅支持 Java 兼容子集,丢失 Kotlin 信息
API 复杂度简洁、Kotlin 友好繁琐、基于 Java 注解处理 API
增量编译原生支持,仅处理变更文件支持有限,易触发全量编译
内存占用低(按需加载符号)高(生成大量 stub)

二、核心概念与架构

1. 核心组件

  • SymbolProcessor:处理器入口,实现 SymbolProcessor 接口,处理符号并生成代码
  • SymbolProcessorProvider:用于发现与实例化处理器,SPI 机制加载
  • Resolver:符号解析器,提供访问所有 Kotlin 符号的 API(类、函数、属性、注解等)
  • CodeGenerator:代码生成器,输出新的 Kotlin/Java 源文件
  • KSPLogger:编译期日志与错误上报

2. 处理流程

  1. 编译触发:Kotlin 编译启动,KSP 插件被加载
  2. 符号收集:Resolver 扫描源码,构建 Kotlin 符号树
  3. 处理器执行:SymbolProcessor.process(resolver, generator) 被调用
  4. 代码生成:通过 CodeGenerator 输出新源码
  5. 合并编译:生成的代码与原代码一起编译为字节码

三、核心 API 与符号模型

1. 核心符号类型

  • KSClassDeclaration:类/接口/对象/枚举声明
  • KSFunctionDeclaration:函数/方法声明
  • KSPropertyDeclaration:属性/字段声明
  • KSAnnotation:注解实例
  • KSType:类型(含泛型、可空性、继承关系)
  • KSValueParameter:函数参数

2. 常用 API 示例

// 1. 获取所有带 @MyAnnotation 的类
resolver.getSymbolsWithAnnotation(MyAnnotation::class.qualifiedName!!)
    .filterIsInstance<KSClassDeclaration>()
    .forEach { cls ->
        // 读取类名、注解参数、父类、属性、函数等
        val className = cls.simpleName.asString()
        val annotation = cls.getAnnotationsByType(MyAnnotation::class).first()
        val value = annotation.arguments.first().value as String
        // ... 分析与生成逻辑
    }

// 2. 生成 Kotlin 代码
generator.createNewFile(
    dependencies = emptyList(), // 依赖文件
    packageName = "com.example.generated",
    fileName = "Generated_$className",
    extensionName = "kt"
).writer().use { writer ->
    writer.write("""
        package com.example.generated
        class Generated_$className {
            fun hello() = println("Hello from $className")
        }
    """.trimIndent())
}

四、快速上手:开发 KSP 处理器

1. 环境配置(Gradle)

// 根目录 build.gradle
plugins {
    id("com.google.devtools.ksp") version "1.9.20-1.0.14" apply false
}

// 模块 build.gradle(处理器模块)
plugins {
    kotlin("jvm")
    id("com.google.devtools.ksp")
}

dependencies {
    implementation("com.google.devtools.ksp:symbol-processing-api:1.9.20-1.0.14")
    ksp("com.google.devtools.ksp:symbol-processing-compiler:1.9.20-1.0.14")
}

// 启用 KSP 生成代码的源码目录
kotlin {
    sourceSets.main {
        kotlin.srcDir("build/generated/ksp/main/kotlin")
    }
}

2. 定义注解

// 定义运行时/编译期注解
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE) // 仅编译期可见
annotation class GenerateHelper(val suffix: String = "Helper")

3. 实现 SymbolProcessor

class MyProcessor : SymbolProcessor {
    override fun process(resolver: Resolver, generator: CodeGenerator, logger: KSPLogger) {
        // 1. 查找所有带 @GenerateHelper 的类
        val annotatedClasses = resolver.getSymbolsWithAnnotation(GenerateHelper::class.qualifiedName!!)
            .filterIsInstance<KSClassDeclaration>()

        annotatedClasses.forEach { cls ->
            val clsName = cls.simpleName.asString()
            val pkg = cls.packageName.asString()
            val suffix = cls.getAnnotationsByType(GenerateHelper::class).first()
                .arguments.first { it.name?.asString() == "suffix" }.value as String
            val generatedName = "${clsName}$suffix"

            // 2. 生成 Helper 类
            generator.createNewFile(
                dependencies = listOf(cls.containingFile!!),
                packageName = pkg,
                fileName = generatedName,
                extensionName = "kt"
            ).writer().use {
                it.write("""
                    package $pkg
                    class $generatedName(private val target: $clsName) {
                        fun sayHello() = println("Hello from $generatedName for ${clsName}!")
                    }
                """.trimIndent())
            }
        }
    }
}

4. 注册处理器(SPI)

在 src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider 文件中添加:

com.example.MyProcessorProvider

5. 实现 ProcessorProvider

class MyProcessorProvider : SymbolProcessorProvider {
    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
        return MyProcessor()
    }
}

6. 使用处理器

在业务模块添加依赖并启用 KSP:

plugins {
    kotlin("jvm")
    id("com.google.devtools.ksp")
}

dependencies {
    // 依赖注解模块
    implementation(project(":annotations"))
    // 依赖处理器模块
    ksp(project(":processor"))
}

使用注解触发生成:

@GenerateHelper(suffix = "Ext")
class User(val name: String, val age: Int)

// 编译后自动生成 UserExt 类
fun main() {
    val user = User("Alice", 20)
    val helper = UserExt(user)
    helper.sayHello() // 输出:Hello from UserExt for User!
}

五、KSP 优势与适用场景

核心优势

  1. 性能飞跃:无 stub 生成、原生增量编译,编译速度提升 30%–80%
  2. Kotlin 原生:完整支持扩展函数、密封类、协程、泛型等特性
  3. API 简洁:基于 Kotlin 语法,学习成本低,代码更易维护
  4. 灵活扩展:支持生成 Kotlin/Java 代码,适配多平台(JVM/Android/JS/Native)
  5. 低内存占用:按需加载符号,避免全量解析

适用场景

  • 注解驱动代码生成:如 Room、Retrofit、Dagger/Hilt、Jetpack Compose
  • 编译期校验:检查注解使用规范、类型安全、命名规范
  • 元编程:生成代理类、Builder、序列化/反序列化逻辑、接口实现
  • 框架开发:构建依赖注入、ORM、RPC 等框架的核心逻辑

六、KSP2 新特性(最新版本)

  • 架构重构:基于 Kotlin 编译器 API,不再是独立插件,与 IDE 共享符号模型
  • 性能再提升:运行在 Gradle daemon,启动更快、增量更精准
  • 更好调试:支持直接在测试中调用入口,调试流程简化
  • 错误处理增强:优雅处理缺失类型,返回 ErrorType 而非崩溃
  • 多平台支持:更好适配 Kotlin Multiplatform

七、总结

KSP 是 Kotlin 生态编译期元编程的标准方案,以高性能、原生 Kotlin 支持、简洁 API 彻底替代 KAPT。它让注解处理与代码生成更高效、更易维护,是现代 Kotlin 框架(如 Compose、Room、Hilt)的底层核心技术。