[컴] java 의 dynamic proxy 예시

 

프록시 / 설명 /

java 의 dynamic proxy 예시

만약 우리가 Test 라는 class를 가지고 있고, 이 class 의 return 값을 변경하고 싶을 수 있다. 그런데 이 class 는 3rd party library 라서 우리가 수정할 수 없다고 하자. 이때 우리가 해볼 수 있는 방식은 다음과 같을 것이다. 다른 좋은 방법은 떠오르지 않는다.

  1. 이럴 때 우리는 dynamic proxy 를 호출하는 다른 class 를 만들고, 그것을 대신 사용하게 할 수 있다. 다만 이때는 다른 public method 도 다 만들어줘야 할 것이다.
  2. Test 를 extend 해서 특정 method 만 override 한다. 이것은 3rd party 에서 열어놨다면 가능하다.
  3. 여기에 Proxy 로 작업하는 것이 들어간다. dynamic proxy

여기서는 위 방법중 3번째 방법을 한 번 살펴보자.

아래코드로 우리는 ITest 에 대한 wrapper class 를 만들 수 있게 됐다. 그럼 이제 원래 Test class 대신에 Proxy 를 사용하도록 하면 된다. 그러면 이제 InvocationHandler.invoke 가 대신 호출 될 것이다.

// Application.kt
package com.example.demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy


fun main(args: Array<String>) {
    val myTestInvocationHandler = DynamicInvocationHandler()
    val test = Proxy.newProxyInstance(Test::class.java.classLoader, arrayOf(ITest::class.java), myTestInvocationHandler) as ITest

    System.out.println(test.testIt())   // 5 가 출력

    val rtest = Test()
    System.out.println(rtest.testIt())  // 11 이 출력

}


internal class DynamicInvocationHandler : InvocationHandler {
    override fun invoke(proxy: Any?, method: Method, args: Array<Any?>?): Any? {
        return if ("testIt" == method.getName()) {
            5
        } else null
    }
}


internal interface ITest {
    fun testIt(): Int
}


internal class Test : ITest {
    override fun testIt(): Int {
        return 11
    }
}

댓글 없음:

댓글 쓰기