프록시 패턴에는 Java의 많은 애플리케이션 시나리오가 있으며 정적 코드와 동적 프록시가 있다. 정적 프록시는 작성, 컴파일 또는 로드 시 코드를 짜서 구현되는 반면, 동적 프록시는 런타임에 구현된다. 간단히 말해서 정적 프록시는 런타임 이전에 존재하는 반면 동적 프록시는 런타임에 존재한다.
동적 프록시에는 두 가지 구현 방식이 있다.
JDK 프록시는 JDK와 함께 제공되며 외부 라이브러리 도입이 필요없다. Java Reflection API를 사용하여 인터페이스를 구현하여 동적으로 프록시 객체를 생성한다.
메서드 호출 시, InvocationHandler의 invoke 메서드를 통해 인터셉트하고 처리한다다.
CGLib는 ASM 기술을 통해 바이트코드 조작 라이브러리를 사용하여 클래스 기반으로 상속을 통해 동적으로 프록시 객체를 생성합니다.
일반적으로 CGLIB는 바이트코드 조작 방식으로 인해 JDK Dynamic Proxy보다 성능이 우수하다. 하지만, 프록시 객체의 활용 방식과 환경에 따라 성능 차이는 달라질 수 있다.
두 가지 방식을 경우에 따라 사용하는 방식을 스프링에서 지원(ProxyFactory)하고 있다.