본문 바로가기

스프링

@target과 @witnin의 차이

@target: 인스턴스의 모든 메서드를 조인 포인트로 적용(부모 메서드까지 어드바이스 적용)

@within: 해당 타입 내에 있는 메서드만(자기 자신 클래스에 정의된 메서드만) 조인 포인트로 적용

package hello.aop.pointcut;

import hello.aop.member.annotation.ClassAop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

@Slf4j
@Import({AtTargetAtWithinTest.Config.class})
@SpringBootTest
public class AtTargetAtWithinTest {

    @Autowired
    Child child;

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

    @Slf4j
    @Aspect
    static class AtTargetAtWithinAspect {

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

        @Around("execution(* hello.aop..*(..)) && @within(hello.aop.member.annotation.ClassAop)")
        public Object atWithin(ProceedingJoinPoint joinPoint) throws Throwable {
            log.info("[@within] {}", joinPoint.getSignature());
            return joinPoint.proceed();
        }
    }

}

실행 결과:

2023-04-17 11:28:15.644  INFO 9812 --- [           main] hello.aop.pointcut.AtTargetAtWithinTest  : child Proxy=class hello.aop.pointcut.AtTargetAtWithinTest$Child$$EnhancerBySpringCGLIB$$ccce1758
2023-04-17 11:28:15.651  INFO 9812 --- [           main] argetAtWithinTest$AtTargetAtWithinAspect : [@target] void hello.aop.pointcut.AtTargetAtWithinTest$Child.childMethod()
2023-04-17 11:28:15.651  INFO 9812 --- [           main] argetAtWithinTest$AtTargetAtWithinAspect : [@within] void hello.aop.pointcut.AtTargetAtWithinTest$Child.childMethod()
2023-04-17 11:28:15.656  INFO 9812 --- [           main] argetAtWithinTest$AtTargetAtWithinAspect : [@target] void hello.aop.pointcut.AtTargetAtWithinTest$Parent.parentMethod()

 

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

@ModelAttribute  (0) 2023.04.23
Aspect와 어드바이저의 차이점  (0) 2023.04.10