1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Java SpringBoot プロジェクトに Kotlin を導入するのが案外簡単だった話

Posted at

はじめに

自分が所属しているプロジェクトでは、Spring Boot を使った Java の Web API を開発しています。
ずっと Java で書かれてきたコードベースですが、「Kotlin って実際どうなの?」という興味から、まずは 1つのアプリケーションサービスを Kotlin に書き換えてみました。

結果から言うと、「思ったよりも簡単に Kotlin を導入できた」です。
本記事ではその手順と気づきを紹介します。

Java 版のコード

まず、既存の Java コードはこちらです👇

package com.example.user.service;

import com.example.user.domain.repository.UserRepository;
import com.example.user.dto.UserDto;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class GetUserService {

  private final UserRepository userRepository;

  public Optional<UserDto> getById(Long id) {
    return userRepository.findById(id).map(UserDto::new);
  }
}

よくある Spring Boot のサービスクラスで、UserRepository からユーザー情報を取得して UserDto に変換するシンプルな処理です。

Kotlin に書き換えたコード

Kotlin 版はこちらです👇

package com.example.order.service

import com.example.user.domain.repository.UserRepository
import com.example.user.dto.UserDto
import org.springframework.stereotype.Service

@Service
class GetUserService(
    private val userRepository: UserRepository
) {
    fun getById(id: Long): UserDto? {
        return userRepository.findById(id)
            .map { UserDto(it) }
            .orElse(null)
    }
}

書き換えのポイント

✅ 変わった点

  • Optional → nullable (UserDto?)
  • map(UserDto::new)map { UserDto(it) }
  • @RequiredArgsConstructor 不要。Kotlin のコンストラクタ引数で依存注入される

🟢 変わらなかった点

  • Spring Boot の @Service アノテーションはそのまま利用可能
  • 既存の Java 製 UserRepository も変更不要で使えました

呼び出し側の変更(Java → Kotlin の境界)

Kotlin の getById は UserDto?(nullable)を返すため、Java 側から呼び出す場合は Optional に包んであげる必要があります。

// Java 側の変更前
Optional<UserDto> userDto = getUserService.getById(id);

// Java 側の変更後
Optional<UserDto> userDto = Optional.ofNullable(getUserService.getById(id));

Kotlin では null ベース、Java では Optional ベースなので、ここで少し変換が入ります。
とはいえ、一行の変更で済む程度でした。

Kotlin をビルドできるようにする設定

Java プロジェクトに Kotlin ファイルを混ぜるためには、build.gradle.kts に Kotlin プラグインを追加する必要があります。

build.gradle.kts
plugins {
    java
    kotlin("jvm") version "2.0.21"
}

tasks.named("compileKotlin") {
    dependsOn(genInboundWsdl)
    dependsOn(genOutboundWsdl)
}

これだけで Kotlin ファイル(.kt)がビルド対象に含まれます。
Java と Kotlin は同じクラスパス上で共存できるため、
既存の Spring Boot プロジェクトにもスムーズに導入できました。

テストコードがほぼそのまま動いた

既存の Java テストコードも、Optional 対応を除けばそのまま動作しました。

@Test
void shouldReturnUserWhenExists() {
  Optional<UserDto> result = Optional.ofNullable(getUserService.getById(1L));
  assertTrue(result.isPresent());
}

このように、修正は最小限でテストはすべてグリーンのままでした ✅
Kotlin は JVM 上で動作し、Java とのバイナリ互換性が完全に保たれているため、
Kotlin クラスを Java からそのまま呼び出すことができます。

Kotlin と Java の自然な共存

面白いのは、実装は Kotlin、テストは Java という構成も問題なく成立することです。

たとえば、

  • 実装側では Kotlin の null 安全や関数型スタイルを活かす
  • テスト側では Java の JUnit Mockito をそのまま使う

といった「混在構成」が簡単に実現できます。

そのため、プロジェクト全体を一気に Kotlin に切り替える必要はなく、
書ける人から少しずつ Kotlin に移行していく段階導入が可能です。

まとめ

実際に Kotlin ファイルを1つ追加してみた感想としては、

  • Spring Boot のアノテーションはそのまま動く
  • Java コードとの相互運用性もほぼ問題なし
  • 実装側は Kotlin 、テスト側は Java といった「混在構成」も可能

つまり、「少しずつ Kotlin 化していく」 アプローチが十分現実的だと感じました。
大きなリファクタリングをしなくても、段階的に Kotlin に置き換えていけそうです。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?