[Spring] Kotllin + Spring boot 시작하기

Spring boot

Spring boot는 JAVA 언어를 기반으로 한 응용프로그램 프레임워크다. 웹 프로그램 뿐만 아니야 다양한 영역에서 사용된다. 본 시리즈에서는 Spring boot 기반 웹프로그램 개발에 초점을 맞추어 진행할 예정이다.

Spring boot가 많이 사용되는 이유가 무엇인지에 대하여 이번 시리즈의 글을 통하여 알아보려고 한다.

Spring boot MVC

프로젝트를 진행함에 있어서 필자는 제일 먼저 구조를 잡는데 시간을 할애한다. 필자는 프로젝트의 개발의 편리성과 유지보수의 용이성은 프로젝트 구조에서 시작된다고 생각한다. Spring 영역에서는 MVC 구조가 보편화 되여 있고 필자가 개발하던 flask(python) 기반의 프레임워크도 MVC 구조로 설계되었다. 구조 부분의 고찰에 대해서는 추후 한편의 글로 정리할 예정이다.

Kotlin

요즘 JVM기반 언어에서 각광 받는 언어이고 안드로이드 개발에서 공식 추천 언어로 사용되고 있다. 국내는 아직 kotlin 기반의 개발 서적과 공유된 글들이 적으나 좋은 인연으로 지단로보트님을 만나게되고 같이 개발하면서 kotlin의 장점과 철할에 대하여 공감하게 되었고 다른 한편으로 현재 python으로 개발해 왔고 pthon의 간결함과 개발 편의성에 반했었다. 그에 반에 python으로 실시간 장애 대응은 힘들고 개발단계에서의 시스템적 오류는 MSA 개발구조상에서 피할 수 없음의 한계를 느끼고 있던 참이 었다. 이 부분도 다른 글로 한번 풀어볼 예정이다. 여기서 계속 풀면 본 글의 목적성과 거리가 멀어지는 것 같다.

Spring boot의 시작

필자도 그랫듯이 Spring boot 프로젝트를 시작하는 방법에는 두가지가 있다.

  • Spring initializr를 이용하는 방법
  • intelliJ 에서 initial spring project를 하는 방법

본 글은 Spring initializr를 이용하여 생성하고 추가로 MVC 구조로 만드는 방법에 대하여 설명하겠다.

Spring initializr

https://start.spring.io/

위 주소로 들어가면 기본적인 구성을 선택할 수 있게 되여 있고 오른쪽에 보시면 Dependencies을 추가할 수 있게 되여 있다. 본 글에서는 아주 간단한 웹 프로그램을 개발하기 위함이므로 아래와 같이 설정하고 생성을 클릭한다.

  • Gradle project
  • spring 진영에는 크게 두가지의 프로젝트 관리 도구인 Maven과 Gradle이 존재한다. Maven은 광범위하게 사용되고 있고 최근에는 Gradle을 사용하여 프로젝트를 많이 진행 한다. 또한 Gradle 설정파일을 kotlin기반으로 작성할 수 있기 때문에 Gradle로 선택햇다.
  • Language에서 kotlin 선택 당연한거죠^
  • Spring Boot에서 2.5.6 버전을 선택 안정적인 release 버전 선택
  • Project Metadata는 기본 설정 그대로 두어도 되고 프로젝트 속성에 맞제 진행하면 된다.
  • JDK 버전은 본인 취향대로 선택하면 된다. 필자는 안정적인 버전을 선호하고 처음 시작하는 단계라 11버전을 선택했다.
  • Dependencies에서는 Spring Web 만 선택하여 추가하자(추후 프로젝트의 커짐에 의해 추가되는 요소는 그때 그때 설명하도록 하겠다)

InteliJ IDE

Kotlin 기반의 프로젝트를 진행함에 있어서 개발사가 제공하는 IDE를 사용하는 것이 제일 바람직하다고 생각한다.

생성된 프로젝트를 InteliJ로 열면 제일 먼저 해야될 일은 build 파일에 대하여 익숙해 지고 친해 져야 한다. 이번 글에서는 간단한 Rest API를 작성하기위한 build 파일을 구성해 본다.

gradle build 작성

다른 글을 참조하면 gradle 문법으로 작성된 build 파일은 많은데 kotlin 기반으로 작성되고 정리된 글은 찾기 힘든것 같은 필자의 추후 추가되는 모든 build 파일은 kotlin 기반으로 작성된다.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
	id("org.springframework.boot") version "2.5.6"
	id("io.spring.dependency-management") version "1.0.11.RELEASE"
	kotlin("jvm") version "1.5.31"
	kotlin("plugin.spring") version "1.5.31"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
	mavenCentral()
}

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
	kotlinOptions {
		freeCompilerArgs = listOf("-Xjsr305=strict")
		jvmTarget = "11"
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

MVC 구조 만들기

생성된 프로젝트는 Application.kt 파일만 존재하고 구조적으로 갖추어진것이 없다. 여기서 간단하게 MVC 구조를 만들기 위하여 controller, service, DTO등 폴더를 추가한다.

  • Controller Request로부터 요청을 받아 처리하는 곳
  • Service Controller에서 요청을 받은 후 비즈니스 로직을 처리하는 부분
  • DTO 계층간 데이터를 교환을 위한 객체, 주로 Entity와 service간 데이터를 주고 받기 위한 객체

Application.kt 파일과 같은 레벨에서 위의 3개의 폴더를 만든다.(만약 다른 곳에 만들면 Spring boot 설정파일에서 bean을 load할 수 있게 지정해 주어야 한다.)

맛보기 프로그램 작성

MVC 프로젝트 진행을 하면 구조의 이점을 충분히 이용할수 있고 이해할 수 있게 만들어야 된다고 생각하고 아래와 같이 작은 시나리오를 구상해 봤다

시나리오

사장자는 웹을 통하여 입력된 단어가 시스템에 있는지 있으면 몇번째 위치에 있는지를 알려준다.

역할 분할

위의 시나리오 기반으로 역할을 분할하면 아래와 같다.

  • Controller 사용자로부터 path parameter로 단어를 입력 받는다
  • Service Controller 부터 전달받은 단어가 시스템에 있는지를 검색하고 존재하면 몇번째에 있는지 반환해 주고 없으면 "no word"라고 반환해 준다.
  • DAO(Repository) 시스템(파일기반, 혹은 메모리 기반)에 Service에서의 요청사항이 있는지를 반환한다.

구현 코드

/src/main/kotlin/com.example.demo/controllor/SearchContorller.kt

@RestController
class SearchController(
    val searchService: SearchService
){
    @GetMapping("/search/{word}")
    fun searchWord(@PathVariable word: String): String{
        return searchService.searchWord(word)
    }
}

/src/main/kotlin/com.example.demo/Service/SearchService.kt

@Service
class SearchService(
    private val wordRepository: WordRepository
) {
    fun searchWord(word: String):String{
        val idx = wordRepository.findWord(word)
        return if(idx==-1){
            "Word is not in repo"
        } else {
            String.format("Word %s is in index of %d",word,idx)
        }
    }
}

/src/main/kotlin/com.example.demo/Repository/WordRepository.kt

@Repository
class WordRepository {
    // 현재 요구사항에 근거하면 수정할 필요 없기 때문에 읽기전용으로 생성
   var wordRep = listOf("key","http","one","two","github","kotlin")
    fun findWord(word: String):Int{
        return wordRep.indexOf(word)
    }
}

컴파일 후 실행하면 원하는 결과가 나온다.

 

 

 

ref: https://jsonobject.tistory.com/219

 

IntelliJ IDEA에서 Spring Boot 웹 프로젝트 생성하기

개요 Spring Boot 는 최근 Java 진영에서 각광 받고 있는 간결하고 강력한 웹 프레임워크이다. 이름에서 드러나듯이 국내에서 가장 사랑 받는 Spring 프레임워크를 기반으로 한다. 경쟁자로 역시 뒤지

jsonobject.tistory.com

https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html

 

[DAO] DAO, DTO, Entity Class의 차이 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

Spring Boot 2 Recipes: A Problem-Solution Approach

 

Spring Boot 2 Recipes: A Problem-Solution Approach

Solve all your Spring Boot 2 problems using complete and real-world code examples. When you start a new project, you’ll be able to copy the code and configuration files from … - Selection from Spring Boot 2 Recipes: A Problem-Solution Approach [Book]

www.oreilly.com

'Spring boot' 카테고리의 다른 글

[Spring]JobRunr libary 사용  (0) 2021.12.19
[Spring] EJB, POJO 그리고 Spring  (0) 2021.12.12
[Spring] Transaction 정리  (0) 2021.11.24
[Spring] Logging 구성 및 구현  (0) 2021.11.22
[Spring] Async 대해  (0) 2021.11.22