aop의 좀 더 다양한 제어 방법에 대해 알아보자.


◆ 호출 메서드 정보 가져오기

자동호출 메서드에서 호출된 메서드에대한 정보를 가져올 수 있다.
자동 호출 메서드가 호출 될 때, 자동 호출 메서드의 인자로 JoinPoint라는 객체를 받게 되면 해당 객체로 호출한 메서드의 정보를 확인할 수 있다.


▶ 메서드 설계

자동 호출 메서드를 설계할 때 매개 인자로 JointPoint객체를 받도록 설계한다.
( ※주의 - JoinPoint는 lang소속의 객체를 써야 한다. ) ex ) public void beforeCut(JoinPoint point)


▶ JointPoint객체의 메서드

  • point.toString()
    호출된 메서드의 풀 경로
  • point.getArgs()
    호출된 메서드의 인자 값을 Object[]배열로 반환
  • point.Target()
    해당 메서드를 호출한 객체를 반환
  • point.Signature().toLongString()
    해당 메서드의 풀 경로
  • point.Signature().toShortString()
    해당 메서드의 짧은 경로 ( 객체.메서드 )

해당 정보는 자동 호출되는 메서드가 아닌 pointcut으로 등록되어 호출 된 메서드에 대한 정보이다.

Ex ) pointcut을 bean(Map객체)로 했을때 map.put(“aa”,”bb”);을 호출할 시

point.toString() : execution(Object java.util.Map.put(Object,Object))
getArgs() : [aa, bb]
getKind() : method-execution
getTarget() : {aa=bb}
getSignature().toLongString() 
: public abstract java.lang.Object java.util.Map.put(java.lang.Object,java.lang.Object)
getSignature().toShortString() : Map.put(..)


◆ after-returning일 때, 자동호출 메서드에서 리턴 데이터 가져오기

호출 타이밍을 after-returnning으로 설정 시 자동호출 메서드의 두 번째 매개 인자로 호출 된 메서드가 반환하는 데이터를 받아올 수 있다.
( after일 때는 오류가 나도 무조건 호출되기 때문에 리턴데이터를 설정할 수 없다. )


▶ after-returning 자동호출 메서드 설계

자동호출메서드를 설계 할 때, 첫 번째 매개 인자로 JointPoint객체, 두 번째 인자로 리턴 된 데이터를 받을 매개 인자를 설정한다.
그리고 자동 호출 메서드를 등록 할 때 returning옵션으로 자동 호출 메서드의 리턴 데이터 변수명과 일치하는 값을 써 주어야 한다.

// aop 설정
<aop:after-returning returning="r" ... /> 
// 자동호출 메서드 설계
public void record(JoinPoint cut, boolean r) 


※ 주의

  • 자동호출 메서드의 JoinPoint는 무조건 첫 번째 인자로 사용한다.
  • 호출한 메서드가 자동호출 메서드의 두번째 인자와 일치하지 않는 타입을 반환할 경우 자동호출 메서드는 호출되지 않는다.


◆ after-throwing일때, AOP메서드에서 발생한 익셉션객체 가져오기

after-throwing일 때는 두 번째 인자로 Exception객체를 받도록 자동 호출 메서드를 설계하면 익셉션이 발생할 시 해당 익셉션 객체를 가져올 수 있다.


▶ 메서드 설계

첫 번째 매개인자로 JointPoint객체, 두 번째 인자로 Exception객체를 받을 매개인자를 설정한다.
또한 returning과 마찬가지로 자동호출 메서드를 등록 할 때 throwing옵션에 해당 Exception변수명과 일치하는 값을 넣어준다.

// aop등록
<aop:after-throwing throwing="e" .. />
// 자동호출 메서드 설계
public void clean(JoinPoint cut, Exception e)

리터닝과 마찬가지로 익셉션이 터질 경우 작동 되는 메서드이다. 주의할 점은 after-returning과 같다.


◆ aop:around

around는 메서드의 시작 전 후로 해야 될 작업을 처리할 수 있으나, 일반적인 방식인 before->after의 형식으로 처리되지 않는다.


▶ around의 작동형태

around로 등록한 pointcut메서드가 호출될 때, 호출 된 메서드가 호출되지 않고 등록시킨 메서드로 바꿔 치기 된다.
따라서 바꿔 치기 된 자동 호출 메서드에서 전/후처리와 예외등을 처리하고 원래의 메서드를 호출할 수 있도록 작동된다.


▶ around메서드 작성법

after/before는 자동 호출되는 메서드에서 JoinPoint객체를 사용하여 호출된 메서드 정보를 불러올 수 있었지만, around는 ProceedingJoinPoint객체를 이용하여 원래의 메서드를 호출할 수가 있다.

  • ProceedingJoinPoint객체.proceed();
     원래의 메서드를 호출 시키는 메서드로, 해당 메서드가 반환하는 데이터를 반환받을 수 있다.
    단, 반환형은 Object형이다. 때문에 around의 자동호출 메서드는 보통 Object객체를 반환하는 메서드로 만들게 된다.
  • proceed()메서드를 사용하기 위해서는 try-catch가 필요하다
  • ProceedingJoinPoint객체는 JoinPoint객체에서 사용하던 메서드들도 사용할 수 있다.
  • ProceedingJoinPoint객체는 around일 때만 사용이 가능하다.
public Object a(ProceedingJoinPoint pjp) {
    System.out.println(“원래의 메서드 시작 전의 작업처리(before));
    try {
        Object val = pjp.proceed(); 
        System.out.println("원래 메서드호출 완료 후의 처리(after-returning)");
        return val;
    } catch (Throwable t) {
        System.out.println("익셉션 발생 시 처리(after-throwing");
        return null;
    } finally {
        System.out.println("무조건 처리(after)");
    }
}
  • 메서드 호출 전의 작업(before)
    proceed()를 호출하기 전에 작성
  • 메서드 호출이 정상 처리된 후 작업(after-returning)
    try문에서 proceed()를 호출 후에 작성
  • 익셉션 발생시의 작업(after-throwing)
    catch(Throwble t )
  • 메서드 호출 후 무조건 호출되는 작업(after)
    finally


▶ 매개변수 처리

proceed() 메서드를 호출할 때, 디폴트로 proceed( .Args )가 자동적으로 매개변수가 들어가면서 되기 때문에 매개변수를 직접 적어주지 않아도 되고 매개변수를 바꿔서 처리할 수도 있지만 굳이 자주 하지는 않는 작업이다.