1. 概要

1月にSpringエコシステムで大きな発表がありました。KotlinのサポートがSpringFramework5に追加されます。 これは、SpringBoot2.xがKotlinをファーストクラスでサポートすることを意味します。

もちろん、これは予想外のことではありません。Pivotalのチームは、ScalaやGroovyなどのJVM言語を受け入れることで知られています。

Spring Bootアプリ2.xを使用してKotlinアプリを作成しましょう!

2. 設定

2.1. 環境

Kotlinは、 IntelliJ Eclipse 、およびコマンドラインでの開発をサポートしています。 指示に従って、好みに基づいて環境を設定します。

2.2. 設定

まず、Spring Boot 2プロジェクトを作成し、依存関係を持つJavaとKotlinのバージョンを指定するエントリを含むようにPOMを変更しましょう。

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jre8</artifactId>
    <version>1.2.71</version>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
    <version>1.2.71</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-kotlin</artifactId>
    <version>2.9.9</version>
</dependency>

Kotlinソースファイルとテストファイルのファイルの場所を指定していることに注意してください。

<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>

Kotlinファイルが別の場所にある場合は、POMでこれらのエントリを変更する必要があります。

Kotlinモジュールとソースをコンパイルするには、 kotlin-maven-plugin:を使用する必要があります

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>1.1.2</version>
    <configuration>
        <compilerPlugins>
            <plugin>spring</plugin>
        </compilerPlugins>
        <jvmTarget>1.8</jvmTarget>
    </configuration>
    <executions>
        <execution>
            <id>compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
        <execution>
            <id>test-compile</id>
            <phase>test-compile</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-allopen</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>
</plugin>

これで、Kotlinアプリケーションを構築するために必要なものがすべて揃いました。 参考: Maven Central spring-boot-starter-web kotlin-stdlib-jre8 kotlin- Reflect jackson-module-kotlin test )。

次に、アプリケーションコンテキストを設定しましょう。

3. アプリケーションコンテキスト

Kotlinコードに飛び込んで、おなじみのSpringBootアプリケーションコンテキストを書いてみましょう。

@SpringBootApplication
class KotlinDemoApplication

fun main(args: Array<String>) {
    SpringApplication.run(KotlinDemoApplication::class.java, *args)
}

おなじみの@SpringBootApplicationアノテーションが表示されます。 これは、Javaクラスで使用するのと同じアノテーションです。

その下に、KotlinDemoApplicationクラスのクラス定義があります。 Kotlinでは、クラスのデフォルトのスコープはパブリックであるため、省略できます。 さらに、クラスに変数と関数がない場合は、中括弧なしで宣言できます。 つまり、本質的には、クラスを定義したばかりです。

メソッドに移ります。 これは、Javaの標準的なJavaエントリポイントメソッドです。 public static void main(String [] args)。

繰り返しになりますが、メソッドまたは関数はデフォルトでパブリックであるため、ここで宣言する必要はありません。 さらに、何も返さない関数は、void戻りタイプを指定する必要はありません。

そして最後に、クラスの本体の外部で定義された関数は自動的に静的になります。 これにより、この関数は起動実行に適格になります。

次に、 mvn spring-boot:runを使用してルートディレクトリからアプリケーションを実行しましょう。 アプリケーションが起動し、アプリケーションがポート8080で実行されていることを確認する必要があります。

次に、コントローラーを作成しましょう。

4. コントローラ

私たちのサービスにコントローラーを追加する方法を見てみましょう。

@RestController
class HelloController {
 
    @GetMapping("/hello")
    fun helloKotlin(): String {
        return "hello world"
    }
}

標準のSpringコントローラーとそれほど違いはありませんが、コードは確かに少なくなっています。 このコントローラーのテストクラスとケースを追加して、作業を検証しましょう。

@RunWith(SpringRunner::class)
@SpringBootTest(classes = arrayOf(KotlinDemoApplication::class), 
  webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class KotlinDemoApplicationTests {

    @Autowired
    lateinit var testRestTemplate: TestRestTemplate

    @Test
    fun whenCalled_shouldReturnHello() {
        val result = testRestTemplate
          // ...
          .getForEntity("/hello", String::class.java)

        assertNotNull(result)
        assertEquals(result?.statusCode, HttpStatus.OK)
        assertEquals(result?.body, "hello world")
    }
}

このテストは、Kotlinの非常に強力な機能の1つであるヌルセーフティを示しています。 nullになる可能性のあるKotlin変数は、「?」を使用して宣言する必要があります。 コンパイラは、そのプロパティにアクセスする前に、防御的なコーディングが必要であることを認識します。

このテストでは、 TestRestTemplate はnull許容型として定義されており、アクセスするたびに、null合体演算子「?」を使用してアクセスします。 –呼び出されたオブジェクトがnullの場合、nullを返します。

これにより、プログラムでのnullの使用が明確になり、開発者はnullを操作するときに安全なコードを作成する必要があります。

次に、サービスを追加して、それをコントローラーに統合しましょう。

5. サービス

ご想像のとおり、私たちのサービスはプロジェクトに簡単に追加できます。 今それをやってみましょう:

@Service
class HelloService {
 
    fun getHello(): String {
        return "hello service"
    }
}

ここでは、文字列を返す単一の関数を使用した非常に単純なサービスです。 次に、サービスをコントローラーに接続し、それを使用して値を返します。

@RestController
class HelloController(val helloService: HelloService) {
 
    // ...
 
    @GetMapping("/hello-service")
    fun helloKotlinService(): String {
        return helloService.getHello()
    }
}

ああ、それはよさそうだ! Kotlinでは、メインコンストラクターをクラス宣言とインラインで定義できます。 @Autowired アノテーションは、しばらくの間必須ではないため、コンストラクターから省略しました。

これらのパラメータは、クラス内のフィールドに自動的に変換されます。 Kotlinはプロパティと呼ばれます。 ゲッターやセッターは定義されていません。 それらは自動的に作成されます。 もちろん、必要に応じてこれらのデフォルトをオーバーライドできます。

Kotlinでは、クラスのプロパティと関数の変数は、varまたはvalを使用して定義できます。 Varは可変プロパティを示し、valは最後のプロパティを示します。これにより、コンパイラは不正アクセスをチェックできます。 HelloService はシングルトンであるため、突然変異を防ぐためにvalとして接続します。

次に、このコントローラーメソッドのテストを追加しましょう。

@Test
fun whenCalled_shouldReturnHelloService() {
    var result = testRestTemplate
      // ...
      .getForEntity("/hello-service", String::class.java)

    assertNotNull(result)
    assertEquals(result?.statusCode, HttpStatus.OK)
    assertEquals(result?.body, "hello service")
}

最後に、POJOがKotlinでどのように表示されるかを見てみましょう。

6. Kotlinデータクラス

Javaでは、データオブジェクトをプレーンオールドJavaオブジェクトであるPOJOで表します。 Kotlinには、このタイプのオブジェクトをより簡潔に表現できるデータクラスがあります。

コントローラに返すデータオブジェクトを書いてみましょう。

data class HelloDto(val greeting: String)

それはトリックではありませんでした。 私はクラスから何も省略していません。 データ修飾子を使用すると、多くのメリットが得られます。 このキーワードは、 equals / hashcode ペア、 toString 関数、およびコピー関数を自動的に作成します。 53文字のワンライナーからすべて!

次に、新しいデータクラスを返すメソッドを追加しましょう。

// ...
@GetMapping("/hello-dto")
fun helloDto(): HelloDto {
    return HelloDto("Hello from the dto")
}

データ修飾子はデフォルトのコンストラクターを追加しません。これは、Jacksonなどの特定のライブラリーにとって重要です。 このタイプのクラスをサポートするために、マーシャリングをサポートするためにjackson-module-kotlinをPOMファイルに追加しました。 これはセクション2で行われ、そこで依存関係を確認できます。

最後に、このコントローラー関数のテストを追加しましょう。

@Test
fun whenCalled_shoudlReturnJSON() {
    val result = testRestTemplate
      // ...
      .getForEntity("/hello-dto", HelloDto::class.java)

    assertNotNull(result)
    assertEquals(result?.statusCode, HttpStatus.OK)
    assertEquals(result?.body, HelloDto("Hello from the dto"))
}

7. 結論

この記事では、SpringBoot2.xでのKotlinのサポートについて説明しました。 例から、Kotlinは、より短く、より安全なコードを作成するように強制することで、アプリケーションを簡素化および強化できることがわかりました。

Kotlinは、データクラス、クラス拡張などのいくつかの驚くべき機能もサポートしており、既存のJavaコードと完全に互換性があります。 これは、Kotlinコードを記述して、Javaクラスから呼び出すことができることを意味します。その逆も可能です。 さらに、KotlinはIDEで素晴らしいサポートを提供するためにゼロから構築されており、実際にサポートされています。

Kotlinを試してみる理由はたくさんありますが、GoogleとSpringが支援しているので、今がKotlinをチェックするときです。 それを使って何を作ることにしたか教えてください!

常に、GitHubでソースコードを見つけることができます。