스프링AOP의 핵심 동작원리는 BeanPostProcessor를 이용한 자동 프록시 생성방법이다. JDK다이나믹 프록시(내지는 CGLib프록시)를 적용하기 위해서는 프록시 생성 대상이 필요하고 이를 선정하는 작업이 BPP를 통해서 일어난다.

Pointcut은 ProxyFactoryBean을 사용해서 직접 타겟(또는 타겟소스)을 지정하지 않는 이프 록시 자동생성의 대상을 선정하는 작업에도 포인트컷터로서 참여한다. 

Pointcut의 생김새는 다음과 같다.

public interface Pointcut {

    ClassFilter getClassFilter();

    MethodMatcher getMethodMatcher();

}

클래스 필터 하나 메소드 매처 하나로 이루어져있다. 메소드 매처는 다시 파라미터를 확인하는지 여부에 따라 스태틱과 다이나믹으로 구분된다.

어쨌든 이것만 보면 자동프록시생성에 참여하는 것은 포인트컷의 ClassFilter일 겄으로 생각하기 쉽다.

하지만 아니다.

중요한 것은 최종 Advice를 적용할 대상 메소드가 존재하는지 여부이기 때문이다. 따라서 자동프록시 생성기들도 클래스필터를 통과했다고 해도 다시 메소드 단위까지 MethodMatcher를 적용해보고 최소한 하나이상의 메소드가 match가 되야 프록시 생성 대상으로 삼는다. AOPUtil의 canApply() 메소드를 살펴보면 이런 작업과정을 파악할 수 있다.

그런데 2.0이전의 유일한 방식이었던 스프링 어드바이저를 이용한 오토프록싱 방식에서는 이 클래스필터가 제법 필터로서 역할을 했다. 사실 클래스필터에서 걸러지지 않으면 메소드매처는 시도조차 할 필요가 없다. 빈 이름을 필터로 사용하는 BeanNameAutoProxyCreator나 커스톰 어드바이저의 클래스필터를 적용하는 DefaultAdvisorAutoProxyCreator등은 당연히 ClassFilter가 중요한 역할을 차지한다.

 

하지만 AspectJ Pointcut Expression을 사용하기 시작한 2.0부터는 조금 다르다. 포인트컷팅을 AspectJ PE에 의지하기 때문이다. 물론 AspectJExpressionPointcut을 이용하기 때문에 역시 Pointcut 인터페이스를 구현한 것은 마찬가지이다. 따라서 ClassFilter가 분명 존재한다. 하지만 AspectJ PE의 경우는 ClassFilter가 우리가 예상할 수 있는 클래스 필터와 다르게 동작한다.

이 ClassFilter는 내부적으로 PointcutExpression의 couldMatchJoinPointsInType()이라는 메소드를 한번 확인할 뿐이기 때문이다. 이 메소드는 단지 이 타입에 조인포인트를 매치해볼 수 있느냐는 확인밖에 안해준다. 스프링AOP는 메소드 실행이 유일한 조인포인트이다. 따라서 메소드가 존재하면 무조건 이 테스트는 통과한다.

따라서 포인트컷 식이 “execution(* a.b.c.XYZ.*(..))"라고 되어있다고 할지라도 XYZ클래스가 아닌 타겟에 대해서도 ClassFilter의 match()는 true를 리턴한다. 결국 포인트컷 표현식가지고 메소드 단위로 적용해보는 MethodMatcher에서야 클래스의 비교까지도 이뤄진다는 점이다.

스프링의 전통적인 Pointcut과 AspectJ EL의 차이점 때문에 발생하는 문제이다. 하지만 ApsectJ EL을 사용해서 스프링의 자동프록시생성 방식을 절묘하게 결합시키는 것을 가능하게했다는 것은 재밌는 일이다.

Pointcut, Advice, Advisor, AutoProxyCreator등의 잘 짜여진 추상화된 모델의 뛰어난 확장성 덕분인듯 싶다.

@Aspect를 사용한 경우라도 내부적으로는 스프링AOP의 자동프록시생성방식을 따르는 AnnotationAwareAspectJAutoProxyCreator에 의해서 프록시가 만들어진다는 것. 이 AutoProxyCreator는 시드니대 88학번인 로드존슨이 이미 2003년에 만든 것이다. AspectJ가 한참 적용되고 발전한 지금까지도 6년째 이 설계는 변하지 않고 잘 적용되고 있다.

 

스프링AOP의 구조와 동작방식을 이해하려면 Profession Spring Programming을 보는 것이 좋다. 내용은 가장 어렵지만 알고나면 짜릿하다. 1.x 때의 내용이지만 2.0이후 지금까지의 스프링AOP의 모든 발전과정을 이해하는데도 아무런 지장이 없을만큼 그 동작원리는 여전하게 유지되고 있다. 나에게 OO설계의 참 맛을 느끼게 해준 대표적인 모델이다.

Related posts:

  1. InsideSpring (3) 스프링 밖에서 WebApplicationContext에 접근하기
  2. InsideSpring (4) 빈 스캐너는 클래스를 로딩할까?
  3. InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (2)
  4. InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (1)
  5. InsideSpring (1) Annotated Factory Method (@Configuration)을 쓰는 4가지 방법 (3)
  6. Spring 3.0 (10) AOP 모듈의 선택 라이브러리 분석
  7. AridPojos – 스프링빈 한방 등록 커스톰 태그
  8. Spring 3.0 (11) Aspects 모듈의 선택 라이브러리 분석
  9. 유쾌한 이슈처리 재촉 메일
  10. 드디어 Spring2.0이 나왔다
  11. 스프링이 쓰는 Dynamic Proxy는 Proxy 패턴인가 Decorator 패턴인가?
  12. 스프링 컨테이너에는 설정파일이 없다
  13. S1A 2008 둘째날 SpringSecurity 2.5

Facebook comments:

to “InsideSpring (2) AutoProxyCreator는 Pointcut의 ClassFilter만 사용하지 않는다”

  1. ryn shoes InsideSpring (2) AutoProxyCreator는 Pointcut의 ClassFilter만 사용하지 않는다 » Toby’s Epril

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha