Spring AOP Pointcut 표현식 - @target, @within

목차

@target 과 @within

클래스에 특정 어노테이션이 적용된 경우 조인 포인트를 매칭

@target@within 은 어노테이션을 기준으로 AOP를 적용하기 위해 사용되는 Pointcut 표현식입니다. 특정 어노테이션이 적용된 클래스내 모든 메서드에 AOP 를 적용합니다.

@target런타임 객체의 실제 타입 을 기준으로 매칭합니다. 이 과정에서 해당 객체의 부모 클래스나 인터페이스에 선언된 어노테이션도 포함하여 검사하기 때문에 부모 타입의 메서드까지 Advice 를 다 적용합니다.

@within 경우 컴파일 시점특정 클래스 에 어노테이션이 선언되었는지를 기준으로 확인하기 때문에 정의된 클래스내 메서드에만 Advice 를 적용합니다.

@target 과 @within 적용 범위

Custon Annotation 생성

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAop {
}

Advisor 생성

@Slf4j
@Aspect
static class AtTargetAtWithinAspect {

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

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

AOP 적용 확인

@Test
void success() {
log.info("child Proxy={}", child.getClass());
child.childMethod(); //부모, 자식 모두 있는 메서드
child.parentMethod(); //부모 클래스만 있는 메서드
}

static class Config {

@Bean
public Parent parent() {
return new Parent();
}
@Bean
public Child child() {
return new Child();
}
@Bean
public AtTargetAtWithinAspect atTargetAtWithinAspect() {
return new AtTargetAtWithinAspect();
}
}

static class Parent {
public void parentMethod(){} //부모에만 있는 메서드
}

@ClassAop
static class Child extends Parent {
public void childMethod(){}
}
2021-12-20 20:45:37.947  INFO 34481 --- [    Test worker] c.e.aop.pointcut.AtTargetAtWithinTest    : child Proxy=class com.example.aop.pointcut.AtTargetAtWithinTest$Child$$EnhancerBySpringCGLIB$$6f94df27
2021-12-20 20:45:37.951 INFO 34481 --- [ Test worker] argetAtWithinTest$AtTargetAtWithinAspect : [@target] void com.example.aop.pointcut.AtTargetAtWithinTest$Child.childMethod()
2021-12-20 20:45:37.951 INFO 34481 --- [ Test worker] argetAtWithinTest$AtTargetAtWithinAspect : [@within] void com.example.aop.pointcut.AtTargetAtWithinTest$Child.childMethod()
2021-12-20 20:45:37.955 INFO 34481 --- [ Test worker] argetAtWithinTest$AtTargetAtWithinAspect : [@target] void com.example.aop.pointcut.AtTargetAtWithinTest$Parent.parentMethod()
Share