Kotlin プロジェクトでアノテーションプロセッサを使用する
- 次の場合は kapt を使用してください:
- Maven プロジェクトを使用している。
- Gradle プロジェクトを使用しているが、必要な Java アノテーションプロセッサがまだ KSP をサポートしていない。サポートされているライブラリのリストを確認する。
- 次の場合は KSP を使用してください:
- Gradle プロジェクトを使用しており、必要な Java アノテーションプロセッサが KSP をサポートしている。
- 独自のアノテーションプロセッサを作成したい。
アノテーションプロセッサは、コンパイル時にソースコードを分析して、ボイラープレートコード(定型コード)を生成したり、使用方法を検証したり、その他のアーティファクトを生成したりします。 Kotlin は、アノテーションプロセッサを操作する 2 つの方法をサポートしています。
kapt コンパイラプラグインは、Kotlin ソースコードからスタブファイルを生成し、そのスタブに対して Java アノテーションプロセッサを実行することで動作します。この追加のスタブ生成ステップによりビルド時間が遅くなり、また kapt は拡張関数や Null 安全などの Kotlin 特有の構造を理解できません。
kapt は Maven と Gradle の両方をサポートしています。すべての Maven プロジェクト、および MapStruct のように KSP をまだ採用していないプロセッサライブラリを使用する Gradle プロジェクトに推奨されます。
KSP フレームワークは、スタブを生成することなく、Kotlin ファーストな API を通じて Kotlin ソースコードを直接読み取ります。Kotlin 特有の機能をネイティブに理解し、kapt よりも高速にビルドを実行します。
現在、KSP は Gradle のみを公式にサポートしています。独自のプロセッサを作成する場合や、Dagger のような KSP 対応ライブラリを使用する場合に推奨されます。
Java アノテーションプロセッサで kapt を使用する
kapt を使用すると、プロセッサ自体に変更を加えることなく、既存の Java アノテーションプロセッサを Kotlin プロジェクトで使用できます。
以下の例は、コンパイル時に Java Beans 間の型安全なマッパー実装を生成する MapStruct アノテーションプロセッサの使用方法を示しています。
ビルドファイルで
kaptプラグインを適用し、dependenciesセクションに MapStruct を追加します。xml<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-pluginのkaptゴールの実行を、compile実行の前に追加します。aptModeオプションを使用して、アノテーション処理のレベルを設定します。
kotlinplugins { kotlin("kapt") version "2.3.0" } dependencies { implementation("org.mapstruct:mapstruct:1.6.3") kapt("org.mapstruct:mapstruct-processor:1.6.3") }groovyplugins { id "org.jetbrains.kotlin.kapt" version "2.3.0" } dependencies { implementation "org.mapstruct:mapstruct:1.6.3" kapt "org.mapstruct:mapstruct-processor:1.6.3" }データクラスとマッパーインターフェースを定義します。
kotlinimport 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) }プロジェクトをビルドします。MapStruct は、生成されたソースのディレクトリに
UserMapperImplクラスを生成します。UserMapperコンパニオンオブジェクトを使用して、生成された実装を呼び出します。kotlinfun 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 プロジェクトで既存のアノテーションプロセッサを使用したり、ソースコード内のアノテーションに基づいてコードを生成する独自のプロセッサを作成したりできます。
Java アノテーションプロセッサで KSP を使用する
Gradle プロジェクトでは、互換性のあるアノテーションプロセッサで KSP を使用してください。KSP は kapt よりも高速で、Kotlin 特有の機能をネイティブに理解できます。すでに KSP をサポートしているライブラリのリストを参照してください。
以下の例は、依存関係グラフの構築コードを生成するコンパイル時の依存関係注入(DI)フレームワークである Dagger の使用方法を示しています。
build.gradle(.kts)ファイルで KSP プラグインを適用し、dependenciesブロックに Dagger を追加します。kotlin// build.gradle.kts plugins { kotlin("jvm") version "2.3.0" id("com.google.devtools.ksp") version "2.3.3" } dependencies { implementation("com.google.dagger:dagger:2.59.2") ksp("com.google.dagger:dagger-compiler:2.59.2") }groovy// build.gradle plugins { id 'org.jetbrains.kotlin.jvm' version '2.3.0' id 'com.google.devtools.ksp' version '2.3.3' } dependencies { implementation 'com.google.dagger:dagger:2.59.2' ksp 'com.google.dagger:dagger-compiler:2.59.2' }KSP の最新バージョンを確認するには、GitHub の Releases ページをチェックしてください。
Kotlin クラスに Dagger アノテーションを付与します。
kotlinimport 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 }プロジェクトをビルドします。Dagger は
build/generated/kspディレクトリにDaggerAppComponentなどの実装クラスを生成します。 コード内で生成されたクラスを使用します。kotlinfun main() { val appComponent = DaggerAppComponent.create() val userRepository = appComponent.userRepository() println("User: ${userRepository.getUser()}") // User: John Doe }
Dagger の KSP サポートに関する詳細は、そのドキュメントを参照してください。
独自のアノテーションプロセッサを作成する
KSP API を使用して、コンパイル時にコードを生成する独自のアノテーションプロセッサを作成できます。 新しいプロセッサには 3 つのモジュールが必要です。
- カスタムアノテーションを宣言する
annotationモジュール。 SymbolProcessorおよびSymbolProcessorProviderファクトリを実装するprocessorモジュール。SymbolProcessorには主要なロジックが含まれ、SymbolProcessorProviderはプロセッサを作成し、META-INF/services/パスにプロバイダーを登録します。- KSP プラグインを適用し、プロセッサに依存し、アノテーションを使用する
appモジュール。
完全なステップバイステップの手順については、KSP クイックスタートを参照してください。
