스택큐힙리스트

Kotlin by 키워드로 3-줄 프록시 완성하기 본문

개발

Kotlin by 키워드로 3-줄 프록시 완성하기

스택큐힙리스트 2025. 7. 21. 19:27
반응형

왜 Kotlin Delegation + Proxy 조합이 핫할까?

Java에선 Proxy.newProxyInstance()·CGLIB 설정이 필수인데, Kotlin은 클래스 위임(class delegation) 문법 하나로 프록시를 뚝딱 만들 수 있다. by 키워드가 “이 인터페이스 구현은 저 객체에 전부 맡겨라”라고 선언해 주기 때문!


핵심 아이디어: 위임 으로 ‘대리 접근’ 꿰차기

Proxy 패턴이 원하는 건 “원본 객체 앞에 서서 접근을 제어”하는 것. Kotlin의 class delegation은 이미 메서드 호출을 원본에게 자동 위임해 주므로, 우리는 오버라이드할 메서드에 로깅·캐싱·권한 체크만 얹으면 끝이다.


코드 ① – 로깅 프록시를 세 줄로

interface OrderService {
    fun placeOrder(id: String)
}

class RealOrderService : OrderService {
    override fun placeOrder(id: String) { /* DB 저장 */ }
}

/* Kotlin Proxy: by + 메서드 오버라이드 */
class LogOrderService(
    private val target: OrderService
) : OrderService by target {               // 자동 위임
    override fun placeOrder(id: String) {   // 필요한 부분만 가로채기
        val start = System.currentTimeMillis()
        target.placeOrder(id)               // 원본 호출
        println("placeOrder took ${System.currentTimeMillis() - start} ms")
    }
}

OrderService by target 한 줄로 나머지 메서드는 모두 전달되니, 핵심 로직 수정 없이 부가기능만 추가된다.


코드 ② – 메모리 캐싱 프록시도 동일 패턴

class CacheOrderService(
    private val target: OrderService,
    private val cache: MutableMap<String, Unit> = HashMap()
) : OrderService by target {
    override fun placeOrder(id: String) {
        if (cache.containsKey(id)) return   // 이미 처리
        target.placeOrder(id)
        cache[id] = Unit
    }
}

위임 프록시 체인을 LogOrderService(CacheOrderService(RealOrderService()))처럼 겹쳐 꽂아도 가독성이 높다.


실전 적용 꿀팁

  1. Spring DI: @Bean fun orderService() = LogOrderService(RealOrderService()) 식으로 교체 주입.
  2. 테스트 더블: 인터페이스만 지켰으니 MockK.spyk()로 LogProxy를 감싼 채 행위 검증 가능.
  3. 퍼포먼스: 리플렉션이 없으니 JDK 동적 프록시보다 호출 오버헤드가 작다.
  4. 한계: 클래스 위임은 단일 타깃만 지원—여러 인터페이스를 합쳐야 하면 여전히 ByteBuddy·CGLIB이 필요하다.

한 줄 요약

Kotlin의 by 위임은 Proxy 패턴을 “XML·리플렉션 없이, 메서드만 살짝 덮어쓰는” 가장 짧은 구현으로 바꿔 준다.

반응형
Comments