[java] 리플렉션을 사용한 동적 프록시 생성

리플렉션(Reflection)은 프로그램 실행 시간(runtime)에 클래스의 정보를 조사하고 활용할 수 있는 기능을 말합니다. 리플렉션을 이용하면 컴파일 시간에 정의되지 않은 클래스나 인터페이스의 메소드, 필드, 생성자 등에 접근할 수 있어, 동적으로 클래스를 로딩하거나 인스턴스를 생성할 수 있습니다.

동적 프록시는 런타임에 인터페이스의 메소드 호출을 가로채어 특정 로직을 수행하는 방식으로 동작하는 객체입니다. 이를 통해 메소드 호출 전후에 추가적인 작업을 수행하거나, 메소드 호출을 가로채어 변경할 수 있습니다.

이번 글에서는 자바의 리플렉션을 이용하여 동적으로 프록시 객체를 생성하는 방법에 대해 살펴보겠습니다.

동적 프록시 생성 예제

다음은 자바에서 리플렉션을 사용하여 동적으로 프록시 객체를 생성하는 간단한 예제 코드입니다.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class DynamicProxyExample {
    public static void main(String[] args) {
        MyInterface realObject = new MyInterfaceImpl();
        MyInterface proxyObject = (MyInterface) Proxy.newProxyInstance(
                DynamicProxyExample.class.getClassLoader(),
                new Class<?>[] { MyInterface.class },
                new MyInvocationHandler(realObject)
        );
        
        proxyObject.doSomething();
    }
}

interface MyInterface {
    void doSomething();
}

class MyInterfaceImpl implements MyInterface {
    public void doSomething() {
        System.out.println("Real object is doing something");
    }
}

class MyInvocationHandler implements InvocationHandler {
    private MyInterface realObject;

    public MyInvocationHandler(MyInterface realObject) {
        this.realObject = realObject;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method execution: " + method.getName() + ", args: " + Arrays.toString(args));
        
        Object result = method.invoke(realObject, args);
        
        System.out.println("After method execution: " + method.getName() + ", result: " + result);
        return result;
    }
}

위 예제에서 Proxy.newProxyInstance 메소드를 사용하여 MyInterface 인터페이스를 구현하는 동적 프록시 객체를 생성하였습니다. MyInvocationHandler 클래스는 InvocationHandler 인터페이스를 구현하여 프록시 객체에서 호출되는 메소드의 동작을 정의합니다.

이제 위 예제를 실행하면, proxyObject.doSomething() 메소드 호출 전후에 추가적인 로깅이 출력되는 것을 확인할 수 있습니다.

이렇게 자바의 리플렉션을 활용하여 동적으로 프록시 객체를 생성할 수 있습니다.

마치며

이번 글에서는 자바 리플렉션을 활용하여 동적으로 프록시 객체를 생성하는 방법에 대해 알아보았습니다. 리플렉션을 이용하면 실행 시간에 동적으로 클래스를 조작하는 다양한 기능을 구현할 수 있으며, 동적 프록시 역시 유용한 디자인 패턴 중 하나입니다.

더 많은 정보는 Oracle Java Documentation를 참고하세요.