예전에 한번 java proxy 기능으로 AOP를 포스팅 한적이 있다.
요기

원래 cglib는 따로 있던 건데 Spring이 가져왔나부다. Spring프로젝트에 포함되어 있다.
우리는 java Proxy로 AOP를 만들 때 단점이 한개 있었다. 그 단점은 바로 인터페이스를 만들어야 하는 이유이다.

class TwiceImpl implements Twice {

    @Override
    public int twice(int x) {
        return x * 2;
    }
}

interface Twice {
    int twice(int x);
}

우리는 예전에 이런 코드를 작성 할때 인터페이스를 만들었어야 했다. 그래야지만 AOP가 동작 한다.
하지만 이제는 인터페이스가 필요 없이도 AOP가 가능하다.
cglib 라는 프로젝트? 라이브러리만 사용하면 된다. 그럼 굳이 인터페이스가 없어도 동작한다.
스프링도 기본으로는 cglib를 사용한다.
일단 코드로 보자. 아래는 org.springframework.cglib.proxy 에 있는 MethodInterceptor 인터페이스다.
spring에 있는 MethodInterceptor와 org.aopalliance.intercept에 있는 MethodInterceptor 인터페이스가 다른게 뭔지는 모르겠다.
비슷한건 맞는데 … 흠

public class CGlibInterceptor implements MethodInterceptor{

  public static void main(String[] args) {
    Twice twice = (Twice) Enhancer.create(Twice.class, new CGlibInterceptor());
    int t = twice.twice(5);
    System.out.println(t);
  }
  @Override
  public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("start");
    Object returnValue = methodProxy.invokeSuper(object, args);
    System.out.println("end");
    return returnValue;
  }

  static class Twice  {
    public int twice(int x) {
      return x * 2;
    }
  }
}

이것 또한 간단하게 두배 해주는 함수를 만들었다.
기존의 java proxy aop와 비슷한 형태를 갖고 있다.

public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy)

이 함수를 보면 object는 원본 객체를 말하고 method 호출될 메소드 args 메소드에서 호출한 파라미터, methodProxy 원본 객체의 메소드 프록시 객체이다.
솔직히 자바가 제공하는 proxy 보다 더 간편하게 사용할 수 있고 더 빠르다고한다.
그냥 말만 들었다. 그렇게…

java의 리플렉션을 사용해서 proxy객체를 만드는 것보다 cglib를 사용하는 것을 추천한다! Spring도 쓰니 추천할 만 하다. 스프링 빠인가 흠..

근데 cglib 샘플 소스중 참 재밌는 것을 발견했다. 보자마자 모지?

  private interface MyFactory {
    Object newInstance(int a, char[] b, String d);
  }
  public static void main(String[] args) {
    MyFactory f = (MyFactory) KeyFactory.create(MyFactory.class);
    Object key1 = f.newInstance(20, new char[]{ 'a', 'b' }, "hello");
    Object key2 = f.newInstance(20, new char[]{ 'a', 'b' }, "hello");
    Object key3 = f.newInstance(20, new char[]{ 'a', '_' }, "hello");
    System.out.println(key1.equals(key2));
    System.out.println(key2.equals(key3));
  }

이런 소스가 있는게 아닌가!!
재밌는 코드가 아닌가? 구현체가 없는데도 생성해준다. 하지만 지켜야할 룰이 있다.
return값은 Object이어야 하며 메소드 명은 newInstance 이어야 한다.
그래도 이게 뭔가 싶었다.
하지만 이걸 어디다 써먹지?

이상으로 cglib의 aop를 알아봤다.