코틀린 마이그레이션

김희영·2025년 11월 3일

spring

목록 보기
17/26

스프링 프로젝트를 점진적으로 코틀린으로 마이그레이션 해보자.

0. 일단은...

일반적으로 원하는 파일을 선택 후 우클릭 -> conver java file to kotlin 하면 된다.
뭔가 잔뜩 물어보는데 전부 네네네 하고 모듈 선택만 잘하면 문제가 없다.

1. 코틀린 버전 확인

근데 이러면 코틀린 버전 중 가장 최신 걸로 된다. 하지만 우리의 스프링부트는 그렇지 않으니 스프링부트가 지원하는 코틀린 버전 보고 맞게 고치자

2. static

코틀린에는 static이 없다. 하지만 java main은 static으로 시작한다.

그래서 이렇게 @jvm 같이 java의 잔재(?)가 남아 있다.

바꿔버려

근데 이러면 빨간줄이 생긴다.
사유: 코틀린은 기본 final인데 그러면 상속이 안됨.
open 달아서 상속 허가하자.

@SpringBootApplication
@EnableJpaAuditing
open class BackendApplication
fun main(args: Array<String>) {
    runApplication<BackendApplication>(*args)
}

아이 좋아

3. 그럼 전부 open?

상속 해주는 모든 클래스에 open을 붙일 생각하니 머리 아프다... 이런 노가다를 피할 수 있음.

kotlin("plugin.spring") version "1.9.25"
kotlin{
    compilerOptions{
        freeCompilerArgs = listOf("-Xjsr305=strict")
    }
}

build.gradle에 이 2개를 추가한다. 그럼 알아서 open 붙여줌

kotlin("plugin.spring") version "1.9.25"
kotlin{	
    compilerOptions{
        freeCompilerArgs = listOf("-Xjsr305=strict")
    }
}

이러면 아까 2에서 붙인 open 없이도 잘된다.
+) 원래 있던 implementation(kotlin("stdlib-jdk8"))는 kotlin("jvm") version "1.9.25"에서 이미 가져오고 있어서 삭제해도 된다.

4. 의존성 추가

그럼 이제 잘쓰는 의존성들을 추가해보자.

jpa 추가

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

jackson와 reflect 자바에서는 기본 포함. 하지만 코틀린은 아니라서 추가

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

allOpen으로 jpa에 필요한 open 자동 달기

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

근데 사실 최신 버전부터는 플러그인 안에 allOpen이 내장 되어 있다... 내가 최신 쓴다 하면 안 넣어도 ok

5. controller

그럼 이제 컨트롤러를 바꿔보자.

conver java file to kotlin!!

음. 역시 딸깍의 한계가 있다. 고치자...

바로 변수 사용

<p>Server IP Address: ${localhost.hostAddress}</p>

associateWith로 빠르게 매핑

return session.attributeNames.toList().associateWith {session.getAttribute(it)}

이런 건 근데 자바스러운 코드를 코틀린스럽게 바꾸는 거라 하나씩 해주는 수 밖에 없긴 하다

6. DTO도 바꿔보자

record->data class


불변성을 위해 record로 되어 있다.
이건 data class로 바꾸는 게 좋다.
conver java file to kotlin!!

굿
참고로 코틀린스럽게 하려고 getter(.getId() -> .id로)는 뺐다.
그리고 이건 Entity도 마찬가지로 @Getter 빼고 직접 만들었다.
그리고 만약을 위해 @JvmRecord는 남겨두자. 마이그레이션이 완벽히 끝나고 지우는 편이 안전하니께
그리고 private constructor를 뒤에 붙이면 주 생성자 대신 부생성자만 쓰게 강제할 수 있다.

class->class

전 record가 아니라 class로 되어 있는데요! 하면 data class가 아니라 그냥 class로 바뀔 것이다. 이때는 다음 형태로 수동 변환하자.

class DTO명 접근제어자 @JvmOverloads constructor( //주 생성자 생성용
    필드들 		//이 필드들로 주 생성자 만듦
) {
    보조 생성자
}

근데 사실 data class로 하는 게 훨씬 좋다. data class 쓰면 equals() / hashCode() / toString() / copy() / componentN() 이런거 자동으로 쓸 수 있다.

+)@JvmOverloads은 val data: T? = null 이런 식으로 기본 값이 있는 필드가 있을 때 java에서도 인지 할 수 있게 해주는 어노테이션이다. 사실 완전 코틀린이면 필요 없는데, 마이그레이션 중이라 붙인다.
+) 우리의 @JsonIgnore... 코틀린에서는 이게 어떤 상황에 무시되는지 적어야한다. @get:JsonIgnore 이렇게

7. 체이닝을 써보자

근데 뻘하게 벨로그에도 토글 버튼 있으면 좋을 것 같지 않냐 왜 없는 거지
암튼 보자
일반적으로 자바의 함수는 (){} 형태다. 하지만 코틀린은 ()=한줄 표현식 할 수 있다.
이때 쓰는 게 체이닝

fun getCookieValue(name: String, defaultValue: String): String =
        request
            .cookies
            ?.firstOrNull { it.name == name }
            ?.value
            ?.takeIf { it.isNotEmpty() }
            ?: defaultValue

이건 Rq에서 쿠키가 있을 때 이름이 있고, 같으면 가져오고 아니면 기본값 가져오는 함수다.
이렇게 간단하게(?) 쓸 수 있다.

8. SecurityConfig

딱 보면 겁내 많다.
스프링 공식 문서로 가서 kotlin Config 찾기 ㄱㄱ
사실 그냥 지피띠니야 해줘 해도 되긴함

글타칸다
맞춰서 적자

@Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {

        http {
            authorizeHttpRequests {
                authorize("/favicon.ico", permitAll)
                authorize("/h2-console/**", permitAll)
                authorize(HttpMethod.GET, "/api/*/posts", permitAll)
            }

            csrf { disable() }

            headers {
                frameOptions { sameOrigin = true }
            }

            addFilterBefore<UsernamePasswordAuthenticationFilter>(customAuthenticationFilter)
            sessionManagement {
                sessionCreationPolicy = SessionCreationPolicy.STATELESS
            }
            
            return http.build()
    }

굿
여기에 정책 따라 추가나 삭제 하면 된다. 로그인 예외처리 같은 거 하면 좋겠쥬

결론

변환 버튼 딸깍 -> 자바스러운 거 코틀린스럽게 수정 -> 테스트 잘 되나 확인
이거 반복하면 됩니더

profile
내는 반드시 엄청난 개발자가 되고 말것어

0개의 댓글