Building web applications with Spring Boot and Kotlin
this tutorial is designed to be completed in 2-3 hours, it provides deeper, in-context explorations of enterprise application development topics, leaving you ready to implement real-world solutions.

kotlin-spring plugin

https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support

kotlin-spring plugin 을 설정하면 @Cofiguration 과 같은 스프링 메타 어노테이션을 대상으로 클래스와 메서드에 open 을 붙인 효과를 준다.

kotlin("plugin.spring") version "1.3.61"

kotlin-jpa plugin & allopen

https://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support

kotlin-jpa plugin 을 설정하면 @Entity, @Embeddable, @MappedSuperclass 3개의 어노테이션에 대해 인자없는 생성자를 자동으로 생성한다. (직접적으로 호출할수는 없고 리플렉션으로 호출 가능) 이것으로 jpa 가 사용 가능해 진다.

kotlin("plugin.jpa") version "1.3.61"

그리고 lazy loading 을 위해서 엔티티가 open 으로 선언되어야 하는데 일일히 선언하는 대신 allopen 플러그인을 사용한다.

plugins {
  ...
  kotlin("plugin.allopen") version "1.3.61"
}

allOpen {
  annotation("javax.persistence.Entity")
  annotation("javax.persistence.Embeddable")
  annotation("javax.persistence.MappedSuperclass")
}

스프링부트 개발에 필요한 그 외 라이브러리들

The different kotlin-stdlibs explained
I love Kotlin as it’s a concise yet powerful language with very sensible defaults and design decisions. In that regard, it adopts the Zen of Python: One area where this failed though is the…

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/index.html

https://github.com/FasterXML/jackson-module-kotlin

  implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
  implementation("org.jetbrains.kotlin:kotlin-reflect")
  implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

kotlin springboot main

@SpringBootApplication
class BlogApplication

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

runApplication<BlogApplication>(*args) 은 원래 SpringApplication.run(BlogApplication::class.java, *args) 라고 해야 하는 대신 사용하는 코틀린 관용구 이다.

JUnit5 & kotlin test

테스트 클래스에서 생성자 주입

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class IntegrationTests(@Autowired val restTemplate: TestRestTemplate) {

  @Test
  fun `Assert blog page title, content and status code`() {
    val entity = restTemplate.getForEntity<String>("/")
    assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
    assertThat(entity.body).contains("<h1>Blog</h1>")
  }

}

@Autowired 붙여서 테스트가 있는 클래스에서 생성자 주입 가능

property 파일을 통해서 전체 프로젝트에 대한 테스트 기본 동작 변경

src/test/resources/junit-platform.properties

junit.jupiter.testinstance.lifecycle.default = per_class

이 설정을 통해서 @BeforeAll@AfterAllcompanion object 안붙이고 일반 메서드처럼 사용 가능하다.

그 외 mock 관련

Ninja-Squad/springmockk
SpringMockK: MockBean and SpyBean, but for MockK instead of Mockito - Ninja-Squad/springmockk
MockK
Provides DSL to mock behavior. Built from zero to fit Kotlin language. Supports named parameters, object mocks, coroutines and extension function mocking
@MockkBean
private lateinit var userRepository: UserRepository

@MockkBean 으로 mock 대상 지정 후

every { articleRepository.findAllByOrderByAddedAtDesc() } returns listOf(spring5Article, spring43Article)

every 로 리턴할 값 지정

Jpa Repository

CrudRepository.findById 대신 Spring Data에서 기본적으로 제공되는 코틀린 extension 인 CrudRepository.findByIdOrNull 을 사용

findById 기반이지만 optional 대신  null 을 반환하는 extention 이다.

ApplicationRunner

초기화 목적으로 기존 자바에서 별도로 상속 후에 인터페이스 구현으로 하던 것과는 달리 메서드에 바로 대입이 가능하다.

@Configuration
class BlogConfiguration {

    @Bean
    fun databaseInitializer(userRepository: UserRepository,
                            articleRepository: ArticleRepository
    ) = ApplicationRunner {

        val smaldini = userRepository.save(User("smaldini", "Stéphane", "Maldini"))
        articleRepository.save(
            Article(
                title = "Reactor Bismuth is out",
                headline = "Lorem ipsum",
                content = "dolor sit amet",
                author = smaldini
            )
        )
        articleRepository.save(
            Article(
                title = "Reactor Aluminium has landed",
                headline = "Lorem ipsum",
                content = "dolor sit amet",
                author = smaldini
            )
        )
    }
}