ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 포인트컷 - execution
    스프링/스프링 AOP 2023. 9. 23. 17:47

    execution의 매칭 조건

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?namepattern(param-pattern) throws-pattern?)

    위의 코드가 포인트컷의 매칭 조건이다. ?가 붙은 것들은 생략을 할 수 있다.

     

    pointcut.setExpression("execution(public String hello.aop.member.MemberServiceImpl.hello(String))");

    아무것도 생략을 하지 않았을 때의 경우이다.

     

     

    매칭 조건 - (?)가 붙은 것들은 생략 가능

    접근제어자(?) : public

    반환타입 : String

    선언타입(?) : hello.aop.member.MemberServiceImpl

    메서드이름 : hello

    파라미터 : (String)

    예외(?) : 생략

     

     

     

    생략할 수 있는 것들을 모두 생략한 execution

    pointcut.setExpression("execution(* *(..))");

    반환타입, 메서드이름 : * - 아무 값이나 들어와도 된다는 뜻

    파라미터 : (..) - 파라미터 타입과 수가 상관 없다는 뜻 

     

     

     

    1. 메서드 이름으로 매칭

    pointcut.setExpression("execution(* *el*(..))");

    메서드 이름 앞 뒤에 *을 넣을 수도 있는데, 이러한 경우에는 el이라는 글자가 들어간 메서드는 전부 포인트컷으로 지정한다는 뜻이다.

     

     

     

     

    2. 패키지 경로로 매칭

     

    2 - 1) 정확한 패키지 경로, 메서드 이름 지정

    pointcut.setExpression("execution(* hello.aop.member.MemberServiceImpl.hello(..))");

    패키지 경로를 정확하게 적어주면 이 패키지에 있는 특정 메서드만 포인트컷으로 지정된다.

    hello.aop.member.타입.메서드이름 순으로 지정해야 한다.

     

     

    2 - 2) * 사용

    pointcut.setExpression("execution(* hello.aop.member.*.*(..))");

    member 패키지에서 *을 사용하면 위와 같은 기능을 수행한다.

     

     

    2 - 3) * 사용시 주의점

    pointcut.setExpression("execution(* hello.aop.*.*(..))"); // 에러

    위와 같은 포인트컷은 에러가 발생한다. 그 이유는 hello.aop.*.*은 패키지 레벨이 안맞기 때문이다.

    하위 패키지를 모두 포함시키고 싶으면 .을 두개 붙이면 된다.

     

     

    2 - 4) 서브 패키지까지 매칭

    pointcut.setExpression("execution(* hello.aop.member..*.*(..))");

    이렇게 해주면 member랑 member 하위가 전부 포인트컷으로 지정된다.

     

     

    2 - 5) 서브 패키지까지 매칭(2)

    pointcut.setExpression("execution(* hello.aop..*.*(..))");

    aop 패키지에서 ..*을 붙여줘도 된다.

     

     

     

     

    3. 타입 매칭

     

    3.1) 부모타입 허용

    pointcut.setExpression("execution(* hello.aop.member.MemberService.*(..))");

    경로를 MemberServiceImpl이 아니라 부모타입인 인터페이스 MemberService 경로로 설정해도 된다. execution에서는 부모타입 = 자식타입이 할당된다.

     

     

    3.2) 구현체에만 있는 메서드를 인터페이스로 접근시

    pointcut.setExpression("execution(* hello.aop.member.MemberService.*(..))");
            
    Method internalMethod = MemberServiceImpl.class.getMethod("internal", String.class);
    assertThat(pointcut.matches(internalMethod, MemberServiceImpl.class)).isTrue(); // 에러 - false임

    MemberService에는 hello라는 메서드만 있고 internal이라는 메서드는 없다. 인터페이스에 선언한 메서드만 포인트컷으로 지정될 수 있기 때문에 MemberService.*으로 설정했을 때에는 되지 않는다.

     

     

     

     

     

    4. 파라미터 매칭

    @Override
    @MethodAop("test value")
    public String hello(String param) {
        return "ok";
    }

    위의 메서드는 파라미터에 String 타입의 param이 들어간다.

     

     

    4 - 1) 파라미터 정확히 지정

    pointcut.setExpression("execution(* *(String))");

    파라미터를 넣는 괄호안에 String을 넣어주는 것이다. 파라미터에 String 타입 하나만 받을 때만 적용된다.

     

     

    4 - 2) 파라미터 하나만 들어오는 경우

    pointcut.setExpression("execution(* *(*))");

    파라미터 괄호 안에 *을 넣으면 아무 타입의 파라미터가 들어와도 된다. 하지만 갯수는 무조건 하나만 들어와야 한다.

     

     

     

    4 - 3)  모든 파라미터 허용

    pointcut.setExpression("execution(* *(..))");

    ..을 넣어주면 숫자와 무관하게 모든 타입을 허용한다. 심지어 파라미터가 없어도 된다.

     

     

     

    4 - 4) 4 - 2와 4 - 3의 복합

     pointcut.setExpression("execution(* *(String, ..))");

    파라미터의 첫 번째는 무조건 String이어야하며, 그 뒤에는 아무 파라미터가 와도 되고 없어도 되는 조건이다.

     

     

     

     

     

     

    포인트컷 지시자의 종류

    1. execution : 메소드 실행 조인 포인트를 매칭한다. 스프링 AOP에서 가장 많이 사용하고, 기능도 복잡하다.
    2. within : 특정 타입 내의 조인 포인트를 매칭한다.
    3. args : 인자가 주어진 타입의 인스턴스인 조인 포인트
    4. this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트
    5. target : Target 객체(스프링 AOP 프록시가 가르키는 실제 대상)를 대상으로 하는 조인 포인트
    6. @target : 실행 객체의 클래스에 주어진 타입의 애노테이션이 있는 조인 포인트

    7. @within : 주어진 애노테이션이 있는 타입 내 조인 포인트
    8. @annotation : 메서드가 주어진 애노테이션을 가지고 있는 조인 포인트를 매칭
    9. @args : 전달된 실제 인수의 런타임 타입이 주어진 타입의 애노테이션을 갖는 조인 포인트
    10. bean : 스프링 전용 포인트컷 지시자, 빈의 이름으로 포인트컷을 지정한다.

     

     

     

    포인트컷 지시자는 많은데 거의 execution만 사용된다. 그렇기 때문에 execution을 이용해서 포인트컷을 지정하는 방법을 정확하게 알고 있어야 원하는 메서드에 aop를 적용할 수 있다.

     

    나머지는 꼭 필요하다 생각되는 시점에 나중에 공부하면 될 것 같다.

    '스프링 > 스프링 AOP' 카테고리의 다른 글

    재시도 AOP  (0) 2023.09.23
    어노테이션으로 AOP 사용  (0) 2023.09.23
    어드바이스 종류  (0) 2023.09.22
    어드바이스 순서  (0) 2023.09.22
    @Pointcut - 포인트컷 분리  (0) 2023.09.22
Designed by Tistory.