모든 조직은 그들만의 용어가 있습니다.
그 용어를 이해하지 못하면서 그 조직을 이해한다는 생각는 오해를 낳을 뿐이죠.
AOP 에서도 그들만의 용어가 있는데 그 용어들을 소스와 비교해서 정리해 보겠습니다.
Aspect
Advisor
Advice
Pointcut
Joinpoint
위 5 가지 용어가 AOP 를 이해하는데 필수이면서 전부인 용어입니다. 그리고 Spring AOP 에 숨어있는 Proxy.. 이건 앞 강좌를 참고하세요.
그럼 쉬운 순서로 설명해 보겠습니다.
Pointcut - 자르는 지점??? Aspect 적용 위치 지정자!!!
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* housework())")
public void before(JoinPoint joinPoint){
System.out.println("얼굴 인식 확인: 문을 개방하라");
//System.out.println("열쇠로 문을 열고 집에 들어간다.");
}
}
위 소스를 보시면 붉은색 부분의 의미는 무엇일까요?
지금 선언하고 있는 메서드(before)를 붉은색 부분의 메서드가 실행되기 전(@Before)에 실행하라는 뜻이 됩니다.
결국 Pointcut 이라고 하는 것은 지금 선언되고 있는 메서드를 적용할 타켓 메서드를 선택하는 지시자(메소드 선택 필터)입니다.
확 줄여보자면 Pointcut 이란 타겟 클래스의 타켓 메소드 지정자가 되겠습니다.
그럼 소제목에서는 왜 Aspect 적용 위치 지정자라고 했을까요?
Spring AOP 만 보자면 Aspect 를 메서드에만 적용할 수 있으니 타켓 메서드 지정자라는 말이 틀리지 않습니다.
그렇치만 AspectJ 처럼 Spring AOP 전에 시작됬고 지금도 유용하게 사용되는 다른 AOP 프레임워크에서는 메서드 뿐만 아니라 속성 등에도 Aspect 를 적용할 수 있기에 그들까지 고려한다면 Aspect 적용 위치 지정자(지시자)가 맞는 말입니다.
토비의 스프링에서는 Pointcut 을 메소드 선정 알고리즘이라고 표현하고 있습니다.
타겟 메서드 지정자에는 익히 알려진 정규식과 AspectJ 표현식 등을 사용할 있는데요.
간단하게 소개해 보자면 다음과 같습니다.
[접근제한자패턴] 리턴타입패턴 [패키지&클래스패턴.]메서드이름 패턴(파라미터패턴) [throws 예외패턴]
여기서 [] 는 생략이 가능하다는 표현이 되겠습니다. 그렇다면 필수적인 요소는 리턴타입, 메서드이름, 파라미터 뿐이군요.
지난 시간에 사용했던 Pointcut 식 2 개를 살펴보겠습니다.
public void aop002.Boy.housework()
접근제한자가 public 이고
리턴타입은 void 이며
aop002 패키지 밑에
Boy 클래스 안에
파라미터가 없으며
던져지는 에러가 있던 없던
이름이 housework 인 메서드(들)를 Pointcut 으로 지정하고 있습니다.
* housework()
접근제한자는 무엇이라도 좋으며(생략되어 있습니다.)
리턴타입도 무엇이라도 좋으며(*)
모든 패키지 밑에(생략되어 있습니다.)
모든 클래스 안에(생략되어 있습니다.)
파라미터가 없으며
던져지는 에러가 있던 없던
이름이 housework 인 메서드(들)를 Pointcut 으로 지정하고 있습니다.
더 자세한 Pointcut 표현식은 역시 책이나 다른 강좌, 특히 Spring API 문서를 추천합니다. ^^
Joinpoint - 연결점??? 연결 가능한 지점!!!
pointcut 은 joinpoint 의 부분 집합이다. 잉 이건 무슨 소리지?
Spring AOP 는 interface 를 기반으로 한다고 설명했었습니다. 그럼 interface 는 또 무엇인가요?
다른 관점에서의 정의도 있지만 interface 는 결국 추상 메서드들의 집합체 입니다.
그럼 삼단 논법에 의해서 Spring AOP 는 메서드에만 적용 가능하다는 결론에 도달하게 되는데..(안 되시나요? 그럼 뭐.. 패쓰)
결국 pointcut 의 후보가 되는 모든 메서드들이 joinpoint 즉, Aspect 적용 가능 지점이 됩니다.
그래서 다시 삼단 논법 joinpint 란 Aspect 적용 가능한 모든 지점을 말한다.
Aspect 적용 가능한 지점 중 일부가 pointcut 이 됨으로 pointcut 은 joinpoint 의 부분집합이다.
요렇게 됩니다.
Spring AOP 에서 joinpoint 란 SpringFramework 가 관리하는 Bean 들의 모든 메서드입니다.
이것이 광의의 Joinpoint 였구요.
소의의 Jointpoint 는 소스 상에서 확인이 가능합니다.
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(* housework())")
public void before(JoinPoint joinPoint){
System.out.println("얼굴 인식 확인: 문을 개방하라");
//System.out.println("열쇠로 문을 열고 집에 들어간다.");
}
}
여기서 붉게 나타나는 joinPoint 는 무엇일까요?
그건 그때 그때 달라요. ^^ 이전 강좌의 Start.java 내용을 참고하실 필요가 있겠네요.
remeo.homework() 을 호출한 상태라면 joinPoint 는 remeo 객체의 homework() 메서드가 되구요.
juliet.homework() 을 호출한 상태라면 joinPoint 는 juliet 객체의 homework() 메서드가 됩니다.
이해 되셨죠. joinPoint 파라미터를 이용하면 Runtime 에 호출된 메서드가 무엇인지, 호출된 메서드를 소유한 객체가 무엇인지, 또 호출된 메서드의 파라미터는 무엇인지 등등 많은 정보를 활용하실 수 있게 됩니다.
정리하죠
광의의 JoinPoint 란 Aspect 적용 가능한 모든 지점
소의의 joinPoint 란 호출된 객체의 메서드
되겠습니다.
Advice - 조언??? 언제 & 무엇을!!!
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(public void aop002.Boy.housework())")
public void before(JoinPoint joinPoint){
System.out.println("얼굴 인식 확인: 문을 개방하라");
//System.out.println("열쇠로 문을 열고 집에 들어간다.");
}
}
advice 는 pointcut 에 적용할 로직 즉, 메서드를 의미하는데 여기에 더해서 언제라는 개념까지를 포함합니다.
결국 advice 란 pointcut 에 언제, 무엇을 적용할 지를 정의한 메서드 입니다.
토비의 스프링에서는 Advice 를 타켓 객체의 타켓 메서드에 적용될 부가 기능이라고 표현하고 있습니다.
위 소스를 보면 지정된 pointcut 의 시작 전(@Before)에 before() 메서드를 실행하라고 되어 있는 것을 보실 수 있습니다.
Aspect - 관점?측면? Advisor 의 집합체
Aspect = Advice 들 + Pointcut 들 = Adivsor 들
더 설명이 필요하신가요?
Advice 는 언제, 무엇을
Pointcut 은 어디에
를 의미함으로 결국 Aspect 는 Where + When + What 이 됩니다.
위 소스를 기반으로 해석해 보면 public void aop002.Boy.housework() 시작 전(@Before)에 before() 메서드를 실행하라고 되어 있는 것을 보실 수 있습니다.
Advisor - 조언자??? 어디서 & 언제 & 무엇을!!!
Advisor = 한개의 Advice + 한 개의 Pointcut
Advisor 는 스프링 AOP 에서만 사용하는 용어입니다. 다른 AOP 프레임워크에서는 사용하지 않는 용어입니다.
지금은 사실 설명을 쉽게 하기 위해 AOP 애너테이션(@)을 사용했었는데요.
다음 강좌에 애너테이션 없는 순수 POJO 와 XML 설정 기반으로 이전 소스를 변경하면서 위에서 설명한 것들이 하나씩 그 모습을 드러낼 겁니다. 기대해 주세요.
결론. 누구였는지 기억이 안 나지만 정말 정말 유명한 화학자 한 분이 이런 말을 하셨다죠.
"무언가에 대해서 초등학교 6학년이 이해하도록 설명하지 못한다면 당신은 그 무언가를 제대로 이해한 것이 아니다."
흠흠.. 제 글 읽으시는 분(?) 중에 초등학교 6학년 이하는 없으시죠?
뭐 제가 쓰지만 초등학교 6학년에게 Spring AOP 를 설명하는 글은 아니라는 건 저도 압니다.
고로 저도 Spring AOP 를 잘 모른다는 거죠. ^^
저는 몽학 선생일 뿐 진정한 스승은 책과 레퍼런스를 다시 강조해 드립니다.
아 더해서 이 글의 정확성에 대한 그 어떠한 법적 책임도 저는 지지 않습니다.
그럼 다시 댓글 1개 이후에 뵙기를...
Be happy!!! Don't worry!!!
P.S 2013.02.18 15:15
키득 키득.. 저의 무식함을 남에게 알리지 마십시요. 제발요. 플리즈.. ㅡㅡ;
만약 네가 그것을 간단하게 설명할 수 없다면, 너는 그것을 충분히 이해하지 못한 것이다. - 알버트 아인슈타인-
만약에 당신이 간단히 설명하지 못한다면, 당신은 그것을 충분히 알고 있는 것이 아니다.
if you can't explain it simply you don't understand it well enough - Albert Einstein
'강좌 > Spring 3.0' 카테고리의 다른 글
013. AOP - 기초 완성 (14) | 2013.01.23 |
---|---|
012. AOP 일단 덤벼 보자 - POJO & XML 기반 AOP (16) | 2013.01.23 |
010. AOP 일단 덤벼 보자 - 설명편 (40) | 2013.01.23 |
009. AOP 일단 덤벼 보자 - 실전편 (5) | 2013.01.22 |
008. AOP - Aspect? 관점? 핵심관심사항? 횡단관심사항? (27) | 2013.01.22 |