bm200.zip
Around Advice를 제외한 Advice 메소드에 첫번개 매개변수로 JoinPoint 타입을 선언할 수 있습니다. Aroud Advice는 JoinPoint의 하위 타입인 ProceedingJoinPoint를 주어야 합니다.

AspectJ API : http://www.eclipse.org/aspectj/doc/next/runtime-api/index.html
위 API를 참조 하시면 어떤 메소드들이 있는지 확인 하실 수 있습니다.

Around Advice는 기능이 다른 Advice들과는 차이가 있습니다.

  • 해당 Join Point를 실행 할지 안할지 정할 수 있습니다.
  • Join Point의 아규먼트로 들어가는 값을 임의로 변경할 수 있습니다.
  • Join Point의 리턴값도 임의로 변경할 수 있습니다.

이를 위해서 두 개의 메소드가 존재합니다.

bl198.bmp

proceed() 메소드는 Join Point를 실행하기 위한 메소드 입니다. proceed()의 리턴 타입은 실제 Join Point에서 리턴하는 값을 리턴 해 줍니다.

proceed(Object[]) 메소드는 Join Point를 실행할 때 Join Point로 들어갈 아규먼트를 대체 하고 싶을 때 원하는 값을 Object 배열 형태로 넣어 줄 수 있습니다.

public class Test {

       public static void main(String[] args) {

 

             BeanFactory bf = new ClassPathXmlApplicationContext(

                           "parameter/joinpoint/aopAppContext.xml");

             Human human1 = (Human) bf.getBean("keesun");

             Human human2= (Human) bf.getBean("youngkun");

 

             System.out.println(human1.getName());

             System.out.println(human2.getName());

 

             human1.setName("찬욱");

 

             System.out.println(human1.getName());

       }

}

위에서 keesun이라는 bean의 name은 "기선" youngkun이라는 bean의 name은 "영근"으로 setter injection을 사용해서 값을 넣어뒀습니다.

@Aspect

public class HumanAspect {

 

       @Pointcut("execution(* get*(..))")

       public void sayHi() {

       }

 

       //리턴 변경하기.

       @Around("sayHi()")

       public Object say(ProceedingJoinPoint joinPoint) throws Throwable {

             System.out.println("안녕하세요.");

             Object name = joinPoint.proceed();

             return name;

       }

 

       //매개 변수의 임의로 변경하기.

       @Around("execution(* set*(..))")

       public void validate(ProceedingJoinPoint pjp) throws Throwable {

             System.out.println("모두 안녕~");

             pjp.proceed(new Object[]{"영회"});

       }

}

그리고 위와 같은 Aspect를 적용하면 결과는 다음과 같습니다.

안녕하세요.
기선
안녕하세요.
영근
모두 안녕~
안녕하세요.
영회

위의 Aspect에서 위에 있던 sayHi Advice를 다음과 같이 수정하면 결과는 다음과 같습니다.

       //리턴 변경하기.

       @Around("sayHi()")

       public Object say(ProceedingJoinPoint joinPoint) throws Throwable {

             System.out.println("안녕하세요.");

             Object name = joinPoint.proceed();

             return ".. 큰일났다.";

       }

 

안녕하세요.
앗.. 큰일났다.
안녕하세요.
앗.. 큰일났다.
모두 안녕~
안녕하세요.
앗.. 큰일났다.

그리고 하지 말라고 하면 더 하고 싶어지는.. 그런 장난끼에 ProceedingJoinPoint말고 그냥 JoinPoint로 선언한 뒤 실행하면 다음과 같은 출력이 됩니다.

안녕하세요.
null
안녕하세요.
null
모두 안녕~
안녕하세요.
null