Kotlin으로 Spring Boot 프로젝트 만들기

Kotlin으로 Spring Boot 프로젝트 만들기 (Create a Spring Boot project with Kotlin)

이 튜토리얼의 첫 번째 파트에서는 IntelliJ IDEA의 프로젝트 마법사(Project Wizard)를 사용해 Gradle로 Spring Boot 프로젝트를 만드는 방법을 다뤄요.

출처: Create a Spring Boot project with Kotlin

본문

이 튜토리얼의 첫 번째 파트는 IntelliJ IDEA에서 Project Wizard를 사용해 Kotlin으로 Spring Boot 프로젝트를 만드는 방법을 보여 줍니다.

이 튜토리얼은 빌드 시스템으로 Gradle을 쓸 필요가 없어요. Maven을 사용해도 같은 단계를 그대로 따라 할 수 있습니다.

시작하기 전에 (Before you start)

최신 버전의 IntelliJ IDEA를 내려받아 설치하고 Ultimate 구독을 사용하세요.

IntelliJ IDEA를 Ultimate 구독 없이 쓰거나 다른 IDE를 사용한다면 웹 기반 프로젝트 생성기로 Spring Boot 프로젝트를 만들 수 있어요.

Spring Boot 프로젝트 만들기

IntelliJ IDEA의 Project Wizard를 사용해 Kotlin으로 새 Spring Boot 프로젝트를 만들어 봅시다.

  1. IntelliJ IDEA에서 File | New | Project를 선택해요.

  2. 왼쪽 패널의 Generators 섹션에서 Spring Boot를 선택합니다.

  3. New Project 창에서 다음 필드와 옵션을 지정해요.

    • Name: demo
    • Language: Kotlin
    • Type: Gradle - Kotlin

    이 옵션은 빌드 시스템과 DSL을 지정해요.

    • Package name: com.example.demo
    • JDK: Java JDK

    이 튜토리얼은 Amazon Corretto version 23을 사용합니다. JDK가 설치되어 있지 않다면 드롭다운 목록에서 내려받을 수 있어요.

    • Java: 17

    Java 17이 설치되어 있지 않다면 JDK 드롭다운 목록에서 내려받을 수 있어요.

  4. 모든 필드를 지정했는지 확인하고 Next를 클릭합니다.

  5. 튜토리얼에 필요한 다음 의존성을 선택해요.

    • Web | Spring Web
    • SQL | Spring Data JDBC
    • SQL | H2 Database
  6. Create를 클릭해서 프로젝트를 생성하고 설정해요.

IDE가 새 프로젝트를 생성하고 엽니다. 프로젝트 의존성을 내려받고 가져오는 데 시간이 좀 걸릴 수 있어요.

  1. 이제 Project view에서 다음과 같은 구조를 확인할 수 있습니다.

생성된 Gradle 프로젝트는 Maven의 표준 디렉터리 구조에 해당해요.

  • 애플리케이션에 속하는 패키지와 클래스가 main/kotlin 폴더 아래에 있어요.
  • 애플리케이션의 진입점은 DemoApplication.kt 파일의 main() 메서드예요.

프로젝트 Gradle 빌드 파일 살펴보기

build.gradle.kts 파일을 열어 보세요. 이 파일은 애플리케이션에 필요한 의존성 목록을 담고 있는 Gradle Kotlin 빌드 스크립트입니다.

이 Gradle 파일은 Spring Boot 표준이지만, kotlin-spring Gradle 플러그인인 kotlin("plugin.spring")을 포함한 필수 Kotlin 의존성도 함께 들어 있어요.

모든 부분과 의존성을 설명한 전체 스크립트는 다음과 같습니다.

// build.gradle.kts
plugins {
 kotlin("jvm") version "2.3.21" // The version of Kotlin to use
 kotlin("plugin.spring") version "2.3.21" // The Kotlin Spring plugin
 id("org.springframework.boot") version "4.1.1"
 id("io.spring.dependency-management") version "1.1.7"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
 toolchain {
 languageVersion = JavaLanguageVersion.of(17)
 }
}

repositories {
 mavenCentral()
}

dependencies {
 implementation("org.springframework.boot:spring-boot-h2console")
 implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
 implementation("org.springframework.boot:spring-boot-starter-webmvc")
 implementation("org.jetbrains.kotlin:kotlin-reflect") // Kotlin reflection library, required for working with Spring
 implementation("tools.jackson.module:jackson-module-kotlin") // Jackson extensions for Kotlin for working with JSON
 runtimeOnly("com.h2database:h2")
 testImplementation("org.springframework.boot:spring-boot-starter-data-jdbc-test")
 testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
 testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
 testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

kotlin {
 compilerOptions {
 freeCompilerArgs.addAll("-Xjsr305=strict", "-Xannotation-default-target=param-property") // `-Xjsr305=strict` enables the strict mode for JSR-305 annotations
 }
}

tasks.withType<Test> {
 useJUnitPlatform()
}

보시다시피 Gradle 빌드 파일에 Kotlin 관련 아티팩트가 몇 개 추가되어 있네요.

  1. plugins 블록에는 Kotlin 아티팩트가 두 개 있어요.

    • kotlin("jvm") 플러그인은 프로젝트에 사용할 Kotlin 버전을 정의합니다.
    • Kotlin Spring 컴파일러 플러그인인 kotlin("plugin.spring")은 Kotlin 클래스에 open 수정자를 추가해서 Spring Framework 기능과 호환되게 만들어요.
  2. dependencies 블록에는 Kotlin 관련 모듈이 몇 개 나열되어 있어요.

    • tools.jackson.module:jackson-module-kotlin 모듈은 Kotlin 클래스와 데이터 클래스의 직렬화·역직렬화 지원을 추가합니다.
    • org.jetbrains.kotlin:kotlin-reflect리플렉션 기능을 완전히 지원하는 Kotlin 리플렉션 라이브러리예요.
  3. 의존성 섹션 뒤에는 kotlin 플러그인 설정 블록이 보입니다. 여기서 컴파일러에 추가 인자를 넘겨 다양한 언어 기능을 켜거나 끌 수 있어요.

Kotlin 컴파일러 옵션에 대해 더 알아보려면 Kotlin Gradle 플러그인의 컴파일러 옵션을 참고하세요.

생성된 Spring Boot 애플리케이션 살펴보기

DemoApplication.kt 파일을 열어 보세요.

// DemoApplication.kt
package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
 runApplication<DemoApplication>(*args)
}

클래스 선언 – class DemoApplication

패키지 선언과 import 문 뒤에서 첫 번째 클래스 선언인 class DemoApplication을 볼 수 있어요.

Kotlin에서는 클래스에 멤버(프로퍼티나 함수)가 없다면 클래스 본문({})을 아예 생략할 수 있습니다.

@SpringBootApplication 애너테이션

@SpringBootApplication은 Spring Boot 애플리케이션에서 쓰는 편의 애너테이션이에요. Spring Boot의 자동 설정(auto-configuration)컴포넌트 스캔을 활성화하고, "애플리케이션 클래스"에 추가 설정을 정의할 수 있게 해 줍니다.

프로그램 진입점 – main()

main() 함수는 애플리케이션의 진입점이에요.

DemoApplication 클래스 밖에 최상위 함수로 선언되어 있습니다. main() 함수는 Spring의 runApplication(*args) 함수를 호출해서 Spring Framework로 애플리케이션을 시작해요.

가변 인자 – args: Array<String>

runApplication() 함수의 선언을 살펴보면 파라미터가 vararg 수정자로 표시된 것을 볼 수 있어요: vararg args: String. 이는 함수에 가변 개수의 String 인자를 넘길 수 있다는 뜻입니다.

전개 연산자 – (*args)

args는 String 배열로 선언된 main() 함수의 파라미터예요. 문자열 배열이 있고 그 내용을 함수에 전달하려면 전개 연산자(spread operator)를 사용하세요. 배열 앞에 별표 *를 붙이는 것이죠.

컨트롤러 만들기

애플리케이션은 실행할 준비가 됐지만, 먼저 로직을 업데이트해 볼게요.

Spring 애플리케이션에서 컨트롤러는 웹 요청을 처리하는 데 사용돼요. DemoApplication.kt 파일과 같은 패키지에 MessageController.kt 파일을 만들고 MessageController 클래스를 다음과 같이 정의합니다.

// MessageController.kt
package com.example.demo

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
class MessageController {
 @GetMapping("/")
 fun index(@RequestParam("name") name: String) = "Hello, $name!"
}

@RestController 애너테이션

Spring에 MessageController가 REST 컨트롤러임을 알려 줘야 하므로 @RestController 애너테이션으로 표시해야 해요.

이 애너테이션 덕분에 이 클래스는 DemoApplication 클래스와 같은 패키지에 있으므로 컴포넌트 스캔에 잡히게 됩니다.

@GetMapping 애너테이션

@GetMapping은 REST 컨트롤러에서 HTTP GET 호출에 해당하는 엔드포인트를 구현하는 함수를 표시해요.

 @GetMapping("/")
 fun index(@RequestParam("name") name: String) = "Hello, $name!"

@RequestParam 애너테이션

함수 파라미터 name@RequestParam 애너테이션으로 표시됩니다. 이 애너테이션은 메서드 파라미터가 웹 요청 파라미터에 바인딩돼야 함을 나타내요.

따라서 /?name=<your-value>처럼 루트에서 "name"이라는 요청 파라미터를 주고 애플리케이션에 접근하면, 그 파라미터 값이 index() 함수를 호출할 때 인자로 사용됩니다.

단일 표현식 함수 – index()

index() 함수는 문이 하나뿐이라 단일 표현식 함수(single-expression function)로 선언할 수 있어요.

즉, 중괄호를 생략하고 본문을 등호 = 뒤에 지정하면 됩니다.

함수 반환 타입의 타입 추론

index() 함수는 반환 타입을 명시적으로 선언하지 않아요. 대신 컴파일러가 등호 = 오른쪽 문의 결과를 보고 반환 타입을 추론합니다.

Hello, $name! 표현식의 타입은 String이므로 함수의 반환 타입도 String이 돼요.

문자열 템플릿 – $name

Hello, $name! 표현식은 Kotlin에서 문자열 템플릿이라고 불러요.

문자열 템플릿은 포함된 표현식을 담고 있는 문자열 리터럴입니다.

문자열 연결(concatenation) 연산을 대신하는 편리한 방법이죠.

애플리케이션 실행하기

이제 Spring 애플리케이션을 실행할 준비가 됐어요.

  1. DemoApplication.kt 파일에서 main() 메서드 옆 거터의 초록색 Run 아이콘을 클릭해요.

터미널에서 ./gradlew bootRun 명령을 실행해도 됩니다.

이렇게 하면 컴퓨터에서 로컬 서버가 시작돼요.

  1. 애플리케이션이 시작되면 다음 URL을 열어 보세요.
http://localhost:8080?name=John

응답으로 "Hello, John!"이 출력되는 것을 볼 수 있어요.

다음 단계 (Next step)

튜토리얼의 다음 파트에서는 Kotlin 데이터 클래스와, 애플리케이션에서 데이터 클래스를 어떻게 사용할 수 있는지 배우게 됩니다.

더 알아보기 (Learn more)