
메서드 시그니처 평균 5.2줄이 1.4줄로, 파일 LOC는 312에서 218로 약 30% 감소했습니다. 코틀린(Kotlin) 2.4 context parameters를 LoggerContext 인자 6개에 적용한 실제 수치예요.
5월 13일 풀린 2.4.0-RC를 사이드 프로젝트 안드로이드(Android) 모듈에 올려둔 지 열흘 정도 되었는데요, 그동안 도메인 레이어 한 곳에 부분 적용해본 후기를 정리해봤어요. 빌드 자체는 RC지만 context parameters API는 이번 RC에서 Stable로 확정된 상태라, 문법만 놓고 보면 정식 릴리스 때 그대로 굳혀도 됩니다.
Kotlin 2.4 context parameters Stable, 무엇이 풀렸나
2.4.0-RC부터 context parameters가 Stable로 승격됐습니다. -Xcontext-parameters 컴파일러 플래그가 빠졌다는 게 가장 큰 변화예요. 더 이상 Gradle 설정에 플래그를 끼워둘 필요가 없어졌습니다.
다만 모든 게 한 번에 풀린 건 아닙니다. 호출부에서 명시적으로 전달하는 context arguments, 그리고 ::process 같은 callable reference는 JetBrains 공식 블로그(Update on Context Parameters) 기준으로 여전히 Experimental로 남아 있어요. 본인 코드에서 이 두 가지를 자주 쓴다면 RC를 그대로 올리기 전 한 번 점검하시는 게 좋겠습니다.
옛 문법인 context receivers(context(Logger))는 deprecated 처리됐습니다. 인텔리J(IntelliJ) 인텐션으로 파일 단위 일괄 변경이 가능하더라고요. 저는 이걸로 모듈 4개를 30분 만에 옮겼습니다.

Hilt·Koin은 그대로 둡니다, 적용 자리는 따로
먼저 짚고 가야 할 게 하나 있는데요, context parameters는 Hilt나 Koin을 대체하는 도구가 아닙니다. 처음 봤을 땐 "이거 DI 프레임워크 안 써도 되는 거 아냐?" 싶었는데 직접 만져보니 역할이 분명히 달랐어요.
Hilt와 Koin은 안드로이드 생명주기에 묶인 전역·컴포넌트 스코프 의존성을 관리합니다. @HiltViewModel, 액티비티/프래그먼트 스코프 바인딩 같은 자리예요. 반면 context parameters는 함수 호출 체인 안에서 이미 주입된 객체를 전파하는 지역 스코프 도구입니다. 컴파일 타임에 정적으로 풀린다는 점이 핵심이에요.
그래서 진가가 살아나는 자리가 ViewModel → UseCase → Repository처럼 길게 이어지는 호출 사슬, 그리고 Hilt를 쓰기 힘든 KMP(Kotlin Multiplatform) 공유 모듈입니다. 저도 KMP 공유 모듈의 Repository 두 개부터 옮겨봤어요.
LoggerContext 인자 6개를 context로 옮긴 실제 diff
가장 효과를 크게 봤던 건 사내 LoggerContext였습니다. 원래는 도메인 함수마다 logger, traceId, userSession, featureFlags, clock, analytics 이렇게 6개가 줄줄이 따라다녔거든요. 이 중 다섯은 그냥 다음 레이어로 흘려보내기만 하는 보일러플레이트였습니다.
// 기존
suspend fun loadFeed(
userId: String,
logger: Logger,
traceId: String,
session: UserSession,
flags: FeatureFlags,
clock: Clock,
analytics: Analytics,
): Feed { ... }
// 변경
context(logger: Logger, session: UserSession, flags: FeatureFlags, clock: Clock, analytics: Analytics)
suspend fun loadFeed(userId: String, traceId: String): Feed {
logger.info("loadFeed start $traceId")
// ...
}
호출부 ViewModel에서는 context(loggerCtx, sessionCtx, flagsCtx, clockCtx, analyticsCtx) { useCase.loadFeed(userId, traceId) } 형태로 한 번에 묶어 넘겨줍니다. 보일러플레이트가 진입점 한 곳에만 모이는 구조가 되더라고요.
수치로 보면 메서드 시그니처가 평균 5.2줄에서 1.4줄로 줄었고, 도메인 모듈 한 파일 기준 LOC가 312에서 218로 약 30% 감소했어요. PR 리뷰할 때 시그니처가 한눈에 들어와서 검토 시간 자체가 짧아진 게 의외의 수확이었습니다.

Hilt와 같이 쓸 때 걸리는 3가지
같이 굴려보면서 조심해야겠다 싶었던 자리를 정리해봤습니다.
- @HiltViewModel 생성자에는 적용 불가입니다. ViewModelProvider.Factory 경로와 충돌하니까, ViewModel 안에서는 suspend fun 메서드 레벨에만 쓰셔야 해요.
- 같은 타입 컨텍스트가 중첩되면 의도치 않은 shadowing이 일어날 수 있습니다. DomainLogger, NetworkLogger처럼 타입을 쪼개 두니 사이드 프로젝트에서는 충돌이 사라졌어요.
- 함수 시그니처만 봐서는 어떤 의존성이 흐르는지 한 번에 안 잡혀요. PR 템플릿에 "이 함수가 받는 context 목록"을 적게 해두는 식의 팀 규칙이 같이 가야 리뷰 비용이 안 늘어납니다.
개인적으로는 세 번째 항목이 진짜 변수라고 봅니다. 코드 줄 수가 줄어든 만큼 암시적인 부분이 늘어난다는 맞바꿈이 있거든요. 저는 PR 설명란에 "이 함수의 context 의존성" 한 줄을 박는 규칙을 사이드 프로젝트에서도 적용해뒀어요.

Kotlin 2.4 Stable 출시 전 선적용 가이드
지금이 RC 단계이니, 전 모듈에 한 번에 바르기보다는 부분 적용으로 감을 잡아두시는 걸 권합니다. 제 경우엔 멀티모듈 프로젝트의 도메인 레이어 한 모듈, 그리고 KMP 공유 모듈의 Repository 1~2개부터 이관해두었어요.
코틀린 버전을 2.4.0-RC로 올리면서 KSP, Hilt, Compose 컴파일러와의 호환성 매트릭스는 반드시 확인하셔야 합니다. 저는 KSP 버전이 한 번 어긋나서 빌드가 통째로 깨졌던 적이 있어서, 라이브러리 버전은 Version Catalog로 한꺼번에 묶어두고 올렸어요.
마이그레이션 PR은 파일 단위로 쪼개는 게 리뷰하는 사람도 편합니다. 인텔리J 인텐션이 한 방에 다 바꿔주긴 하는데, 그걸 한 PR에 다 담으면 변경 줄 수가 700~800줄씩 나와서 리뷰가 멈춰버리더라고요. 모듈 → 패키지 → 파일 순으로 잘게 나누는 쪽이 통과 속도가 훨씬 빨랐습니다.
순수 단일 모듈 안드로이드 앱이라면 RC 단계에서 무리해서 들어갈 필요는 없다고 봅니다. 호출 사슬이 길거나 모듈 경계를 자주 넘는 코드에서 효과가 큰 도구인데, 단일 모듈에서는 체감이 그만큼 크지 않았어요. 저도 메인 앱 모듈은 일단 Stable 정식 릴리스까지 두고 보기로 했습니다.
'Android 개발 > Kotlin' 카테고리의 다른 글
| IntelliJ IDEA 2026.1 코루틴 인스펙션, 6년차 코드를 17번 찌르다 (0) | 2026.06.08 |
|---|---|
| KMP 2.3 production-ready 선언, 6년차 안드러가 본 진짜 도입선 (0) | 2026.06.02 |
| Kotlin 2.3.20 name-based destructuring, 안드 코드 7곳에 끼워본 일주일 (0) | 2026.06.01 |
| Kotlin 2.4.0-RC 풀렸다 — context parameters 안정화·name-based destructuring 본인 코드에 한 시간 적용 (0) | 2026.05.27 |
| 코루틴 처음 만났을 때 가장 헷갈렸던 것들 (0) | 2026.05.04 |