Spring AOP는 프록시 패턴을 이용하여 AOP를 구현한다.
프록시 패턴은 클라이언트가 실제 서비스 객체에 접근하는 것이 아니라 프록시 객체를 통해 접근하는 것이다.
프록시 객체는 실제 서비스 객체에 접근하는 역할을 하며, 클라이언트는 프록시 객체를 통해 서비스 객체에 접근한다.
프록시 객체는 클라이언트가 서비스 객체에 접근하기 전에 추가적인 기능을 수행할 수 있다.
이러한 프록시 객체를 프록시 패턴이라고 한다.
특정한 인터페이스를 노출 시키고 싶지 않고 , 외부로 부터 감추고 싶을 때 사용한다.
Spring AOP의 프록시는 디자인 패턴의 프록시와는 다르다.
Spring AOP의 프록시는 프록시 객체가 실제 서비스 객체를 상속받아 구현한다.
따라서 프록시 객체는 실제 서비스 객체의 메소드를 호출할 수 있다.
이러한 특징 때문에 Spring AOP의 프록시는 디자인 패턴의 프록시보다 더 많은 기능을 수행할 수 있다.
관심사의 추출은 다음과 같은 방식으로 수행된다.
Proxy를 이용한 런타임 위빙(Runtime Weaving) 을 통해서 관심사를 추출할 수 있다.
여기서 Runtime Weaving 이란?
Weaving is the process of applying aspects to a target object to create a new, proxied object.
-> Weaving은 target 객체를 새로운 proxied 객체로 적용시키는 과정이다.
그래서 Runtime Weaving은?
Spring AOP의 프록시는 두 가지 방법으로 구현할 수 있다.
JDK Dynamic Proxy는 JDK 1.3부터 지원하는 기능이다.
JDK Dynamic Proxy는 인터페이스를 기반으로 프록시 객체를 생성한다.
이 프록시는 InvocationHandler 인터페이스를 상속 받아 구현한다.
InvocationHandler 인터페이스는 다음과 같이 정의되어 있다.
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
InvocationHandler 인터페이스는 다음과 같은 역할을 수행한다.
JDK Dynamic Proxy는 다음과 같은 단점이 있다.
CGLIB는 Code Generation Library의 약자이다.
CGLIB는 Enhancer 클래스를 이용해서 프록시 객체를 생성한다. (상속)
Enhancer 클래스는 다음과 같이 정의되어 있다.
public class Enhancer {
public static Object create(Class superclass, Callback callback);
public static Object create(Class superclass, Class[] interfaces, Callback callback);
}
Enhancer 클래스는 다음과 같은 역할을 수행한다.
CGLIB는 다음과 같은 장점이 있다.
위 두 가지 방법은 모두 프록시 패턴을 구현하는 방법이다.
JDK Dynamic Proxy의 invoke() 메소드와 CGLIB의 intercept() 메소드는
@Advice 의 개념과 일치한다.