Spring AOP - Pointcut 표현식 execution

목차

execution

execution( [접근제어자] 리턴타입 [선언타입] 메서드이름 (파라미터) [예외] )

execution 는 Pointcut 표현식에서 가장 많이 사용되는 명시자 입니다.

execution 는 메소드의 접근 제어자, 리턴 타입, 메소드가 선언된 패키지, 클래스 정보, 메소드 파라미터, 예외처리 정보를 이용해 다양한 조건으로 Pointcut 을 적용할 수 있도록 제공합니다.

execution(public String com.example.aop.member.MemberServiceImpl.hello(String))

  • 접근 제어자 : public 인 메소드
  • 리턴 타입 : String
  • 선언 타입 : com.example.aop.member.MemberServiceImpl
  • 메서드 이름 : hello
  • 파라미터 : String
  • 예외 : 생략
@Test
void exactMatch(){
// public java.lang.String com.example.aop.member.MemberServiceImpl.hello(java.lang.String)
pointcut.setExpression("execution(public String com.example.aop.member.MemberServiceImpl.hello(String))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}

모든 메소드를 대상으로 한 포인트 컷 - execution(* *(..))

  • 접근 제어자 : 생략
  • 리턴 타입 : *
  • 선언 타입 : 생략
  • 메서드 이름 : *
  • 파라미터 : (..)
  • 예외 : 없음
pointcut.setExpression("execution(* *(..))");

Method 지정

execution( [접근제어자] 리턴타입 [선언타입] 메서드이름 (파라미터) [예외] )

execution 에 특정 메소드 정보를 기입할 경우 해당되는 메소드에 Advice 가 적용됩니다. 메소드 이름에 * 를 넣은 경우 모든 대상으로 Advice 가 적용되고 특정이름으로 시작하거나 포함하거나 끝나는 경우에는 이름 정보와 * 를 조합하면 조건에 맞는 메소드만 Advice 를 적용할 수 있습니다.

// hello 인 메소드에 Advice 를 적용합니다.
execution(* hello(..))

// hel 로 시작하는 메소드에 Advice 를 적용합니다.
execution(* hel*(..))
// 메소드 이름에 el 이 들어가는 메소드에 Advice 를 적용합니다.
execution(* *el*(..))

선언 타입 지정

execution( [접근제어자] 리턴타입 [선언타입] 메서드이름 (파라미터) [예외] )

선언 타임의 경우 패키지와 클래스 정보로 구성됩니다.

패키지와 클래스를 이용한 지정, 특정 패키지만 지정, 하위 패키지까지 지정, 구현 클래스 지정, 인터페이스 혹은 상위 클래스 지정, 특정 패키지 정보와 클래스를 지정하는 방법등을 통해 Advice 를 적용할 수 있습니다.

특정 Package 내 Class 를 지정

패키지와 클래스를 명시하면 해당 패키지내 클래스 메소드를 대상으로 Advice 를 적용할 수 있습니다.

execution(* com.example.aop.member.MemberServiceImpl.hello(..))

Package 내 모든 클래스에 적용

패키지에 속한 모든 클래스를 대상으로 Advice 를 적용하고 싶다면 패지키 정보 만 명시하고 클래스 정보* 를 넣으면 해당 패키지 내 모든 클래스 메소드에 AOP 를 적용합니다.

다만, 하위 패키지 클래스에는 적용되지 않습니다.

// com.example.aop.member 패키지 내 클래스에 Advice 가 적용
execution(* com.example.aop.member.*.*(..))

// com.example.aop.member 패키지 내 클래스에는 Advice 가 적용되지 않습니다.
execution(* com.example.aop.*.*(..))

하위 Package 내 클래스에 AOP 적용

패키지를 명시할 경우 해당 패키지내 객체를 대상으로만 Advice 가 적용됩니다. 만일 하위 패키지까지 적용하고 싶다면 .. 를 넣어주면 하위 패키지내 객체들까지 Advice 적용할 수 있습니다.

// com.example.aop.member 하위 패키지 클래스까지 AOP 를 적용합니다.
execution(* com.example.aop.member..*.*(..))

// com.example.aop 하위 패키지 클래스까지 AOP 를 적용합니다.
execution(* com.example.aop..*.*(..))

부모 타입 지정 - 자식 타입에 적용

부모 타입을 대상으로 하는 Pointcut 은 자식 타입을 대상으로도 동일하게 적용됩니다. 따라서, 구현 혹은 상속을 통해 자식 타입에도 Advice 를 적용할 수 있습니다.

부모 타입을 지정하면 Pointcut 의 대상은 부모 타입에 정의된 메소드에만 적용할 수 있습니다 즉, 자식 타입에서 선언한 메서드는 Pointcut 대상이 될 수 없습니다.

// 부모 타입을 지정하면 자식 타입에도 적용됩니다.
pointcut.setExpression("execution(* com.example.aop.member.MemberService.*.*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();

// 자식 타입에서 선언한 메소드는 AOP 가 적용되지 않습니다.
// internal 메소드는 MemberServiceImpl 클래스에서 선언한 메소드라 AOP 적용대상이 아닙니다.
pointcut.setExpression("execution(* com.example.aop.member.MemberService.*.*(..))");
Method internalMethod = MemberServiceImpl.class.getMethod("internal", String.class);
assertThat(pointcut.matches(internalMethod, MemberServiceImpl.class)).isFalse();

Parameter 지정

execution( [접근제어자] 리턴타입 [선언타입] 메서드이름 (파라미터) [예외] )

메소드에서 사용하는 Paramater 를 대상으로 Advice 를 적용할 수 있습니다. 표현식을 이용해 단일, 한개 이상, 모든 파라미터를 대상으로 적용할 수 있습니다.

// String 파라미터를 사용하는 메소드에 Advice 적용
execution(* *(String))
// 파라미터가 없는 메소드만 Advice 적용
execution(* *())
// 하나의 파라미터만 가진 메소드에 Advice 적용
execution(* *(*))
// 모든 파라미터형식의 모든 메소드에 Advice 적용
execution(* *(..))
// 특정 파라미터로 시작하고 모든 파라미터형식의 메소드에 허용
execution(* *(String, ..))
Share