김영한의 스프링 핵심 원리(고급편) - 포인트컷 지시자(execution 등)

2025. 2. 25. 00:55·김영한의 스프링 핵심 원리 - 고급편

Question

  • execution의 모든 인자를 설명하시오
  • 다음을 설명하시오
    • within
    • args
    • this
    • target
    • @target
    • @within
    • @annotation
    • @args
    • bean

 

 

포인트컷 지시자의 종류

  • execution : 메소드 실행 조인 포인트를 매칭한다. 스프링 AOP에서 가장 많이 사용하고, 기능도 복잡하
    다.
  • within : 특정 타입 내의 조인 포인트를 매칭한다.
  • args : 인자가 주어진 타입의 인스턴스인 조인 포인트
  • this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트
  • target : Target 객체(스프링 AOP 프록시가 가리키는 실제 대상)를 대상으로 하는 조인 포인트
  • @target : 실행 객체의 클래스에 주어진 타입의 애노테이션이 있는 조인 포인트
  • @within : 주어진 애노테이션이 있는 타입 내 조인 포인트
  • @annotation : 메서드가 주어진 애노테이션을 가지고 있는 조인 포인트를 매칭
  • @args : 전달된 실제 인수의 런타임 타입이 주어진 타입의 애노테이션을 갖는 조인 포인트
  • bean : 스프링 전용 포인트컷 지시자, 빈의 이름으로 포인트컷을 지정한다

 

 

execution 문법

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

execution(접근제어자? 반환타입 선언타입?메서드이름(파라미터) 예외?)

ex) execution(public String hello.aop.member.MemberServiceImpl.hello(String))
  • ?는 생략할 수 있음
  • * 같은 패턴을 지정할 수 있음
  • 예시 분석
    • 접근제어자?: public
    • 반환타입: String
    • 선언타입?: hello.aop.member.MemberServiceImpl
    • 메서드이름: hello
    • 파라미터: (String)
    • 예외?: 생략


가장 생략 많이한 포인트컷

execution(* *(..))
  • 접근제어자?: 생략
  • 반환타입: *
  • 선언타입?: 생략
  • 메서드이름: *
  • 파라미터: (..)
  • 예외?: 없음
  • *는 아무 값이 들어와도 된다는 뜻
  • ..는 파라미터 타입과 수가 상관 없다는 뜻(0..*)

 

패키지 맵핑 관련 포인트컷

  • hello.aop.member.*(1).*(2)
  • (1): 타입
  • (2): 메서드 이름
  • 파라미터가 나오기전 . 뒤 맨 마지막은 메서드 이름임
  • 그 전에는 패키지 경로
  • . 는 정확하게 해당 위치의 패키지를 의미
  • ..는 해당 위치의 패키지와 그 하위 패키지도 포함한다는 의미
  • 패키지는 부모 타입으로 선언하면 자식 타입도 매칭됨
  • 만약 부모 타입으로 선언했느네 부모에 없는 함수를 선언하면 맵핑되지 않음

 

 

파라미터 매칭

//String 타입의 파라미터 허용
execution(* *(String))

//파라미터가 없어야 함
execution(* *())

//정확히 하나의 파라미터 허용, 모든 타입 허용
execution(* *(*))

//숫자와 무관하게 모든 파라미터, 모든 타입 허용
//파라미터가 없는 것도 가능
execution(* *(..))

//String 타입으로 시작, 숫자와 무관하게 모든 파라미터, 모든 타입 허용
//(String), (String, Xxx), (String, Xxx, Xxx) 허용
execution(* *(String, ..))

 

 

 

within

within(hello.aop.member.MemberServiceImpl)

within(hello.aop.member.*Service*)

within(hello.aop..*)
  • 타입(클래스나 인터페이스)이 매칭되면 그 안의 메서드(조인 포인트)들이 자동으로 매칭 됨
  • execution에서 타입 부분만 사용한다고 보면 됨
  • execution과 다르게 표현식에 부모 타입 지정 불가하며, 정확하게 타입이 맞아야 함

 

args

args(String)

args()

args(..)

args(*)

args(String,..)

args(java.io.Serializable)
  • 타입만 보고 매칭
  • execution의 타입 매칭과 다른 점은 args는 부모 타입도 허용
  • 예를 들어 String은 Serializable을 구현하므로 args에서는 String을 받아도 가능하지만 execution에서는 안됨

 

@within

@Aspect
@Component
public class MyAspect {

    // @MyAnnotation 애노테이션이 붙은 클래스 내부의 모든 메서드에 적용
    @Pointcut("@within(com.example.annotation.MyAnnotation)")
    public void annotatedWithMyAnnotation() {}

    @Before("annotatedWithMyAnnotation()")
    public void logBefore() {
        System.out.println("Method in a class annotated with @MyAnnotation is about to execute.");
    }
}

// 이 클래스의 모든 메서드는 AOP가 적용됨
@MyAnnotation
public class MyService {
    public void doSomething() {
        // 코드
    }
}
  • @within은 특정 애노테이션이 붙어 있는 타입(클래스)의 내부 메서드들에 대해 포인트컷을 적용하는 데 사용함.
  • 쉽게 말해서, 어떤 클래스가 특정 애노테이션을 가지고 있으면 그 클래스의 메서드들에 AOP를 적용할 수 있음.
  • 컴파일 타임에 적용, 특정 애노테이션이 붙은 클래스 내부의 모든 메서드에 대해서 AOP 적용

@target

@Aspect
@Component
public class MyAspect {

    // @MyAnnotation 애노테이션이 붙은 프록시 객체의 모든 메서드에 적용
    @Pointcut("@target(com.example.annotation.MyAnnotation)")
    public void proxyAnnotatedWithMyAnnotation() {}

    @Before("proxyAnnotatedWithMyAnnotation()")
    public void logBefore() {
        System.out.println("Method in a proxy object annotated with @MyAnnotation is about to execute.");
    }
}

// 이 클래스의 모든 메서드는 런타임 시점에 프록시 객체가 AOP 적용
@MyAnnotation
public class MyServiceImpl implements MyService {
    public void doSomething() {
        // 코드
    }
}
  • @target은 프록시 객체가 특정 애노테이션을 가지고 있는지에 따라 포인트컷을 적용하는 데 사용함.
  • 즉, 해당 애노테이션이 런타임 시점에 프록시 객체 타입에 적용된 경우에만 메서드 호출에 AOP를 적용함.
  • 런타임 타임에 적용, 특정 애노테이션이 붙은 프록시 객체의 모든 메서드에 대해서 AOP 적용

 

@annotation

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

@Slf4j
@Aspect
static class AtAnnotationAspect {

	@Around("@annotation(hello.aop.member.annotation.MethodAop)")
	public Object doAtAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
		log.info("[@annotation] {}", joinPoint.getSignature());
		return joinPoint.proceed();
	}
}
  • 어노테이션을 가지고 있는 메서드에 조인포인트를 매칭

 

@args

@Service
public class MyService {

    public void performAction(@Auditable String data) {
        System.out.println("Performing action with data: " + data);
    }
}

@Aspect
@Component
public class MyAspect {

    // @Auditable 애노테이션이 붙은 인자를 가진 메서드에 적용되는 포인트컷 정의
    @Before("@args(com.example.Auditable)")
    public void logBeforeAnnotatedArgs() {
        System.out.println("A method with an @Auditable argument is about to execute.");
    }
}
  • @args는 메서드 호출 시, 인자들이 특정 애노테이션을 가지고 있는 경우에 매칭되는 포인트컷을 정의할 때 사용
  • 예를 들어, 메서드 인자 중 하나 또는 여러 개가 특정 애노테이션으로 표시된 경우에만 AOP를 적용가능

 

bean

@Aspect
static class BeanAspect {
    
    @Around("bean(orderService) || bean(*Repository)")
    public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("[bean] {}", joinPoint.getSignature());
        return joinPoint.proceed();
    }
}
  • 스프링 전용으로, 빈의 이름으로 조인포인트 매칭

 

 

매개변수 전달

 //joinPoint.getArgs()[0] 와 같이 매개변수를 전달 받는다
 @Around("allMember()")

 // args(arg,..) 와 같이 매개변수를 전달 받는다.
 @Around("allMember() && args(arg,..)")

 //@Before 를 사용한 축약 버전이다. 추가로 타입을 String 으로 제한했다
 @Before("allMember() && args(arg,..)")

 //프록시 객체를 전달 받는다.
 @Before("allMember() && this(obj)")

 //실제 대상 객체를 전달 받는다.
 @Before("allMember() && target(obj)")

 //@target 타입의 애노테이션을 전달 받는다.
 @Before("allMember() && @target(annotation)")

 //@within 타입의 애노테이션을 전달 받는다.
 @Before("allMember() && @within(annotation)")

 // @annotation : 메서드의 애노테이션을 전달 받는다.
 @Before("allMember() && @annotation(annotation)")
  • 매개변수 전달: this, target, args,@target, @within, @annotation, @args
  • 포인트 컷의 이름과 매개변수의 이름을 맞춰야함
  • 여기서는 arg로 맞춤

 

this vs target

  • this: 스프링 빈 객체(프록시)를 대상으로 하는 조인 포인트
  • target: 타겟 객체(가리키는 실제 대상)를 대상으로 하는 조인 포인트
  • this는 프록시 생성 전략에 따라 JDK 동적 프록시가 나올수도, CGLIB이 나올수도 있음

'김영한의 스프링 핵심 원리 - 고급편' 카테고리의 다른 글

김영한의 스프링 핵심 원리(고급편) - 총 정리  (0) 2026.01.19
김영한의 스프링 핵심 원리(고급편) - AOP 실무 예제  (0) 2025.02.25
김영한의 스프링 핵심 원리(고급편) - AOP의 포인트컷, AOP의 어드바이스 종류  (0) 2025.02.25
김영한의 스프링 핵심 원리(고급편) - @Aspect, AOP  (0) 2025.02.24
김영한의 스프링 핵심 원리(고급편) - 빈 후처리기  (0) 2025.02.22
'김영한의 스프링 핵심 원리 - 고급편' 카테고리의 다른 글
  • 김영한의 스프링 핵심 원리(고급편) - 총 정리
  • 김영한의 스프링 핵심 원리(고급편) - AOP 실무 예제
  • 김영한의 스프링 핵심 원리(고급편) - AOP의 포인트컷, AOP의 어드바이스 종류
  • 김영한의 스프링 핵심 원리(고급편) - @Aspect, AOP
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      @within
      Target
      버퍼
      프록시
      requset scope
      jdk 동적 프록시
      typequery
      cglib
      단방향 맵핑
      @discriminatorcolumn
      @discriminatorvalue
      페치 조인
      스레드
      양방향 맵핑
      락
      빈 후처리기
      gesingleresult
      자바
      김영한
      hibernate5module
      프록시 팩토리
      JPQL
      Thread
      고급
      WAS
      jpq
      log trace
      조회 성능 최적화
      reentarantlock
      @args
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    김영한의 스프링 핵심 원리(고급편) - 포인트컷 지시자(execution 등)
    상단으로

    티스토리툴바