개인공부

포인트컷 지시자의 종류

lby132 2024. 1. 9. 13:07

포인트컷 표현식은 `execution` 같은 포인트컷 지시자(Pointcut Designator)로 시작한다. 줄여서 PCD라 한다.

 

포인트컷 지시자의 종류

`execution` : 메소드 실행 조인 포인트를 매칭한다. 스프링 AOP에서 가장 많이 사용하고, 기능도 복잡하다.
`within` : 특정 타입 내의 조인 포인트를 매칭한다.

@Test
void withinExact() {
    pointcut.setExpression("within(hello.aop.member.MemberServiceImpl)");
    assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}

@Test
void withinStar() {
    pointcut.setExpression("within(hello.aop.member.*Service*)");
    assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
@DisplayName("타켓의 타입에만 직접 적용, 인터페이스를 선정하면 안된다.")
void withinSuperTypeFalse() {
    pointcut.setExpression("within(hello.aop.member.MemberService)");
    assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isFalse();
}

@Test
@DisplayName("execution은 타입 기반, 인터페이스 선정 가능")
void executionSuperTypeTrue() {
    pointcut.setExpression("execution(* hello.aop.member.MemberService.*(..))");
    assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}


`args` : 인자가 주어진 타입의 인스턴스인 조인 포인트

@Before("allMember() && args(arg,..)")
public void logArgs3(String arg) {
    log.info("[logArgs3] arg={}", arg);
}

`this` : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트

@Before("allMember() && this(obj)")
public void thisArgs(JoinPoint joinPoint, MemberService obj) {
    log.info("[thisArgs]{}, obj={}}", joinPoint.getSignature(), obj.getClass());
}


`target` : Target 객체(스프링 AOP 프록시가 가리키는 실제 대상)를 대상으로 하는 조인 포인트

@Before("allMember() && target(obj)")
public void targetArgs(JoinPoint joinPoint, MemberService obj) {
    log.info("[targetArgs]{}, obj={}", joinPoint.getSignature(), obj.getClass());
}

`@target` : 실행 객체의 클래스에 주어진 타입의 애노테이션이 있는 조인 포인트

//@target: 인스턴스 기준으로 모든 메서드의 조인 포인트를 선정, 부모 타입의 메서드도 적용
@Around("execution(* hello.aop..*(..)) && @target(hello.aop.member.annotation.ClassAop)")
public Object atTarget(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("[@target] {}", joinPoint.getSignature());
    return joinPoint.proceed();
}

`@within` : 주어진 애노테이션이 있는 타입 내 조인 포인트

//@within: 선택된 클래스 내부에 있는 메서드만 조인 포인트로 선정, 부모 타입의 메서드는 적용되지 않음
@Around("execution(* hello.aop..*(..)) && @within(hello.aop.member.annotation.ClassAop)")
public Object atWithin(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("[@within] {}", joinPoint.getSignature());
    log.info("gggghi");
    return joinPoint.proceed();
}


`@annotation` : 메서드가 주어진 애노테이션을 가지고 있는 조인 포인트를 매칭

@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();
    }
}

아래 코드 처럼 어노테이션 안의 값을 가져올수도 있음.

// MethodAop 안에 있는 value() 를 꺼낼 수 있다.
@Before("allMember() && @annotation(annotation)")
public void atAnnotation(JoinPoint joinPoint, MethodAop annotation) {
    log.info("[@annotation]{}, obj={}", joinPoint.getSignature(), annotation.value());
}


`@args` : 전달된 실제 인수의 런타임 타입이 주어진 타입의 애노테이션을 갖는 조인 포인트

`bean` : 스프링 전용 포인트컷 지시자, 빈의 이름으로 포인트컷을 지정한다.

@Around("bean(orderService) || bean(*Repository)")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("[bean] {}", joinPoint.getSignature());
    return joinPoint.proceed();
}

'개인공부' 카테고리의 다른 글

Cglib  (0) 2024.01.03
jdk동적프록시  (0) 2024.01.03
security 요청 설정  (0) 2023.07.08
SSL의 동작방법  (0) 2023.03.21
빌드  (0) 2022.11.10