개발 등/SPRING

[펌글]POJO클래스를 이용한 AOP 작성

darkhorizon 2009. 4. 2. 20:47
728x90
반응형

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은 다음에 살펴보자... -_-;;

728x90