우아한 테크 세미나 : 어디 가서 코프링 매우 알은 체하기

우아한 테크 세미나 : 어디 가서 코프링 매우 알은 체하기

DSL (Domain Specific Language) : 도메인에 특화된 언어, 즉 범용적인 언어가 아닌 (해당 도메인에 대해서만) 사용되는 언어.

이번 세미나의 내용은 간략하게 아래의 내용을 포함하고 있다.

  1. Kotlin DSL 에 대해 살펴보고
  2. Kotlin 사용 시 주의사항 (with SpringBoot)

개요 #

  1. 코틀린은 JVM, 안드로이드, Javascript, 네이티브 등에서 동작할 수 있는 (혹은 이것들을 대상으로 하는) 컴파일 언어이다.
  2. OO(Object-Oriented), FP(Functional-Programmin) 두 스타일 모두 활용할 수 있다.
  3. 간결하고, 실용적이다. (+ 최근에 ‘코루틴’ 이라는 것이 주목받고 있다고 한다.)

아이템 1 : (코틀린의) 표준 라이브러리를 사용한다. #

자바 라이브러리(+ 외부 라이브러리)보다 코틀린 표준 라이브러리를 사용한다.

  • 이후에 JVM, Javascript, Android 등의 코드를 하나의 코드로 만든다고 가정했을 때에도, 코틀린에서 제공하는 라이브러리를 쓴다면 충돌할 일은 없을 것이다.
  • ‘표준’ 사용은 언제나 권장된다.
  • 되도록 Java 라이브러리 사용을 자제해보자.

아이템 2 : ‘Java’로 역컴파일하는 습관을 들여보자. #

처음 코틀린이 어색할 때에는 의도치 못한 실수를 방지하기 위해서라도 Java 로 역컴파일하여 생성된 코드를 확인해보자.

코드가 어떻게 생겼는지 확인하고, 이해해보자.


아이템 3 : ‘Lombok’ 대신 Data 클래스를 사용할 수 있다. #

Data 클래스는 equals(), hashcode(), toString(), copy() 등의 기능을 자동으로 생성해준다.

  • 덕분에 코드가 훨씬 간결해진다.
    • (클래스 코드가 간결해지기 때문에) 하나의 (kt)파일에 (관련이 있는)여러 클래스를 작성하는 것도 좋은 방법이라고 한다.

* 참고 : kt1.5 부터 Java 16 이상부터 지원하는 record 키워드도 지원한다. 즉, Kotlin 에서는 Java 와 최대한 같이 사용될 수 있도록 많은 지원을 하고 있다.


필드 주입이 필요하다면, ‘지연 초기화’를 사용하자. #

생성자 주입이 권장되고 있지만, 때로는 필드 주입이 필요할 수도 있다. 이렇게 필드 주입이 필요하다면 lateinit(지연 초기화) 를 사용할 수 있다.

lateinit + var 키워드를 통해 지연 초기화를 사용할 수 있다.

이 덕분에 (원래대로라면) nullable field 를 만들어야 하는 것을 nullable 하지 않게 만들 수도 있다. (좀 더 찾아보자.)


‘변경 가능성’ 을 제한하자. #

val 를 기본으로 사용하고, 필요 시에만 var 를 사용하자.




기타 #

All-open 컴파일러 플러그인 #

Spring 의 경우, 프록시 메커니즘에 의해 ‘상속’을 허용해야 하는 부분들이 많이 있다.

코틀린에서는 final 이 기본이다.
따라서, 이를 위해 open 키워드를 통해 상속을 허용해주어야 하는데, 수많은 클래스에 이 키워드를 다시 작성해주어야 하는 비효율성이 있다.

이것을 해결하기 위해 제공하는 플러그인, ‘all-open 컴파일러 플러그인’ 이라고 한다.

@Transactional, @Configuration, @Async 등의 지정된 어노테이션 사용 시 내부적으로 open 키워드를 (클래스, 필드 모두에)삽입해준다고 한다.

스프링 이니셜라이저를 통해 프로젝트 생성 시 기본적으로 포함되어 있다고 한다.


어노테이션 #

코틀린의 경우 프로퍼티가 아래의 역할을 한다.

  1. 생성자 매개변수
  2. getter
  3. setter
  4. 필드

이 중 어떤 곳에 어노테이션을 적용시키고 싶은가?

내부적으로 알아서 필요한 곳에 적용이 된다고 한다. 하지만 이것들을 정확하게 확인하지 못해 놓치는 부분도 많다고 한다.

이런 경우를 위해 아래와 같이 어노테이션을 적용할 곳을 지정할 수 있다.

data class My(
    @param:JsonProperty("my_id")
    @get:JsonProperty("my_id)
    val id: String,

    @param:JsonProperty("my_name")
    @get:JsonProperty("my_name")
    val name: String,
    val amount: Long,
    ...
) {
    constructor(...) : this(
        ...
    )
}

코틀린 모듈 #

많은 라이브러리, 프레임워크에서 코틀린을 위해 많은 지원을 하고 있다고 한다.

예를 들어, ‘잭슨 라이브러리’는 기본생성자를 만들기 귀찮은 코틀린을 위해 기본생성자가 없더라도 직렬화/역직렬화가 가능하도록 기능을 제공한다고 한다.

코틀린 환경에서 objectMapper 설정에 주의하자.

ObjectMapper().registerKotlinModule() 과 같이 꼭 코틀린 모듈을 등록해주어야 한다고 한다.


Backing Property(뒷받침하는 프로퍼티) #

(클래스에) 동일한 기능/필드이지만,

- 하나는 공개된 API
- 다른 하나는 내부적으로만 사용하는 API (예 : 구현 세부사항 등)

이렇게 두 개의 프로퍼티가 있는 경우, private 프로퍼티 이름의 접두사로 밑줄을 사용한다.

private val _students: MutableSet<Student> = students.toMutableSet()
val students: Set<Student>
    get() = _students

(위의 예시 처럼) 클래스 내부에서는 mutable 한 필드를 사용하고, 외부에 반환 시에는 immutable 상태로 반환할 수도 있다.

* JVM 에서는 기본 getter 및 setter 가 있는 private 프로퍼티에 대해 함수 호출 오버헤드를 방지하도록 최적화 되어 있다고 한다. (이 부분은 좀 더 찾아볼 것.)


KotlinDetector 클래스 확인해볼 것 #


코틀린(+ 자바) 컴파일 순서 #


작성 중…