Spring 2.x 버전부터는 API를 사용하지 않고 POJO를 이용해서 AOP를 적용할 수 있다..
POJO를 이용한 AOP를 위해서는 ASM 라이브러리가 필요로 한데..
2.5 버전은 spring.jar에 포함되어 있으니 신경쓸 필요 없다...
자 그럼 한 번 살펴보도록 하자...
먼저 POJO 기반 AOP는 XML 스키마를 이용하여 설정해준다..
<beans> 태그에 아래처럼 xmlns를 추가해준다...
<beans ...
xmlns:aop=http://www.springframework.org/schema/aop ... >
aop란 네임 스페이스를 등록했다면 다음과 같이 AOP 설정을 한다...
<bean id="test" class="test.aop.TestAspect"/>
<aop:config>
<aop:aspect id="testAspect" ref="test">
<aop:pointcut id="publicMethod" expression="execution(public * test.service..*(..))"/>
<aop:around pointcut-ref="publicMethod" method="testMethod"/>
</aop:aspect>
</aop:config>
<bean id="testService" class="test.service.TestService"/>
먼저 test 빈은 공통 기능을 구현한 빈이라고 가정하자...
AOP 설정은 <aop:config> 태그로 시작하고 <aop:aspect> 태그의 ref 속성에는 공통 기능을 구현한 빈을 넣어준다..
위의 예제에서는 test 빈이 공통 기능을 구현했다고 했으므로 ref에는 test가 설정되어있다...
<aop:pointcut> 태그에는 Advice를 적용할 Pointcut을 expression 속성에 AspectJ 표현식으로 설정해준다...
AspectJ 표현식은 잘 모르는 관계로 관심 있는 사람은 따로 찾아보도록 하자...
아무튼 위의 표현식은 test.service 패키지와 그 하위 패키지에 있는 모든 클래스에 대해서...
public인 모든 메소드에 대하여 Pointcut을 지정하겠다는 의미라고 한다...
Advice를 설정하기 위해 위의 예제에는 <aop:around>란 태그가 쓰였는데...
pointcut-ref 속성에는 위에 지정한 Pointcut을 지정하고 method에는 실제 실행할 메소드를 지정한다...
위의 예제에서는 test 빈의 testMethod를 호출하겠다는 말이 된다...
Advice를 지정하기 위해 <aop:around> 말고도 사용할 수 있는 태그는 다음과 같다..
<aop:before> 메소드 실행 전에 적용
<aop:after-returning> 메소드가 정상 실행된 후에만 적용
<aop:after-throwing> 메소드가 예외를 발생시킬 때에만 적용 (catch문과 비슷)
<aop:after> 메소드가 실행된 후 무조건 적용 (finally문과 비슷)
<aop:around> 모든 시점에 적용
Advice 설정에는 pointcut-ref 속성 말고 pointcut이란 속성도 있는데...
pointcut 속성에는 <aop:pointcut> 태그의 expression 속성을 바로 설정해줄 수 있다...
위의 예제는 아래와 같이 사용할 수 있다..
<aop:config>
<aop:aspect id="testAspect" ref="test">
<aop:around pointcut="execution(public * test.service..*(..))" method="testMethod"/>
</aop:aspect>
</aop:config>
설정은 다 살펴보았다...
이제 직접 Advice를 만들어 보도록 하자..
POJO를 이용하기 때문에 일반 자바 클래스를 만들듯이 만들면 된다...
각 Advice별로 알아보도록 하자..
<aop:before>나 <aop:after>를 이용한다면 Advice 클래스에는 다음과 같은 메소드를 구현해준다..
public void testMethod([JoinPoint joinPoint])
{
}
대상 객체나 호출 메소드 정보를 얻고자 한다면 매개변수로 JoinPoint를 넘겨준다..
<aop:after-returning>은 다음과 같다..
public void testMethod([JoinPoint joinPoint, Object ret])
{
}
역시나 추가적인 정보가 필요하다면 매개변수로 JoinPoint를 넘겨주자..
만약 메소드의 리턴 값을 사용하고자 한다면 매개변수에 추가로 Object를 넘겨주고...
<aop:after-returning> 태그의 returning 속성에 위의 메소드에서 정의한 매개변수 이름을 넘겨준다...
즉... 다음과 같이 설정해주면 된다....
<aop:after-returning ... returning="ret" ... />
여기서 한가지 주의할 점은.. 만약 JoinPoint를 매개변수로 넘기고자 할 때는..
꼭 첫 번째 매개변수로 넘겨야 한다는 사실이다..
그렇지 않으면 예외가 발생하게 된다...
이번엔 <aop:throwing> 을 알아보자...
public void testMethod([JoinPoint joinPoint, Exception ex])
{
}
추가 정보가 필용하면 JoinPoint를 넘겨주자..
만약 발생한 예외가 필요한 경우 매개변수에 해당 예외 클래스를 넘겨주고...
<aop:throwing> 태그의 throwing 속성에 위의 메소드에서 정의한 매개변수의 이름을 넘겨준다..
<aop:throwing ... throwing="ex" ... />
마지막으로 <aop:around> 태그를 알아보자...
이건 이전 글에서 봤던 MethodInterceptor와 같은 기능을 하는 태그이다..
public Object testMethod(ProceedingJoinPoint joinPoint)
{
...
Object ret = joinPoint.proceed();
...
return ret;
}
<aop:around> 같은 경우에는 무조건 매개변수로 ProceedingJoinPoint를 전달받아야 한다..
그리고 대상 객체의 메소드를 실행하려면 꼭 proceed 메소드를 호출해야 한다...
여기까지 POJO를 이용한 AOP 설정을 알아보았다..
점점 글이 길어지는 관계로 @Aspect Annotation은 다음에 살펴보자... -_-;;
[출처] POJO 클래스를 이용한 AOP|작성자 따굴찬