잡동사니

Dynamic Proxy와 CGlib의 차이점 본문

IT/Java

Dynamic Proxy와 CGlib의 차이점

yeTi 2020. 1. 20. 11:25

안녕하세요. yeTi입니다.

Spring AOP를 공부하다보면 Java의 Dynamic ProxyCGlib이 언급됩니다.

그래서 Dynamic Proxy와 CGlib에 대해서 정리하고 차이점을 알아보고자 합니다.

프록시 패턴

Dynamic ProxyCGlib은 기존 코드에 변경을 가하지 않으면서 기능을 추가할 수 있는 프록시 기술을 구현하기 위한 방법들입니다.

소프트웨어 디자인 패턴 중 하나인 프록시 패턴을 UML로 표현하면 아래 그림과 같습니다.

프록시 패턴의 주요 개념은 동일한 인터페이스를 가진 구현 클래스는 Client에서 사용할때 다형성을 활용하여 동일한 인터페이스에 다른 기능을 정의하여 사용할 수 있는 것입니다.

Dynamic Proxy

프록시 패턴을 직접 구현하는 경우에 프록시 클래스를 직접 구현해야하고 코드량이 많아지는 문제점이 있습니다.

이에 자바에서 리플렉션을 활용한 Proxy 클래스를 제공하고 있고 이를 사용하면 런타임시에 동적으로 기능을 추가할 수 있습니다.

BookService bookService = (BookService) Proxy.newProxyInstance(BookService.class.getClassLoader(), new Class[]{BookService.class}, 
    new InvocationHandler() {
        BookService bookService = new DefaultBookService();
        @Override
        public Object invoke(Object proxy, Method, method, Object[] args) throws Throwable {
            if (method.getName().equals("rent")) {
                System.out.println("aaaa");
                Object invoke = method.invoke(bookService, args);
                System.out.println("bbbb");
                return invoke;
            }

            return method.invoke(bookService, args);
        }
    });

해당 방식의 제약 사항은 인터페이스를 통해서만 Proxy를 생성할 수 있다는 것입니다.

CGlib

위에 Dynamic Proxy의 제약사항을 언급했던거와 같이 클래스의 프록시가 필요한경우에는 다른 방법은 사용해야 하는데

그 방법 중 하나가 CGlib을 활용하는 것인데, 이미 스프링이나 하이버네이트에서는 내장되어 사용하고 있습니다.

MethodInterceptor handler = new MethodInterceptor() {
    BookService bookService = new DefaultBookService();
    @Override
    public Object intercept(Object interceptor, Method, method, Object[] args, MethodProxy methodProxy) throws Throwable {
            if (method.getName().equals("rent")) {
                System.out.println("aaaa");
                Object invoke = method.invoke(bookService, args);
                System.out.println("bbbb");
                return invoke;
            }

            return method.invoke(bookService, args);
        }
    });

BookService bookService = (BookService) Enhancer.create(BookService.class, handler);

CGlib의 제약사항은 final 클래스나 메소드는 advise할 수 없다는 것입니다.

AspectJ

Spring AOP는 AspectJ 스타일로 제공합니다.

이 말이 무엇이냐면 AspectJ라는 용어는 이클립스 제단에서 주관하는 프로젝트명으로 AOP를 도입할 수 있도록 기능을 제공하는 프로젝트 입니다.

Spring AOP에서 AspectJ의 기능 중 Pointcut을 파싱하고 매칭해주는 제한적인 AOP를 제공합니다.

AspectJ가 제공하는 다양한 기능을 사용하고 싶으면 5.10. Using AspectJ with Spring Applications를 참고하면 됩니다.

Comments