본문 바로가기
Spring|Spring-boot/Spring AOP

Spring AOP 매개변수 활용

by oncerun 2022. 1. 30.
반응형

 

this. target, args, @target, @within, @annotation, @args의 지시자들은 표현식을 사용해

어드바이스에 매개변수를 전달할 수 있다.

 

1. 포인트 컷의 이름과 매개변수의 이름을 맞추어야 한다.

2. 타입이 메서드에 지정한 타입으로 제한된다.

 

 

@Test
void success() {
    log.info("memberService Proxy= {}", memberService.getClass());
    memberService.hello("helloA");
}

@Slf4j
@Aspect
static class ParameterAspect {

    @Pointcut("execution( * hello.aop.member..*.*(..))")
    public void allMember(){}

    @Around("allMember()")
    public Object logArgs1(ProceedingJoinPoint joinPoint) throws Throwable {
        Object arg = joinPoint.getArgs()[0];
        log.info("signature = {}, arg = {}" , joinPoint.getSignature(), arg);
        return joinPoint.proceed();
    }


}

 

우리의 관심은 memberService.hello()를 호출할 때 넘어가는 "helloA"라는 인자에 관심을 두고 있다. 

 

가장 간단하게 받을 수 있는 방법은 joinPoint의 getArgs()로 인자들의 배열을 받고 인덱스를 통해 인자를 얻는 방법이다.

signature = String hello.aop.member.MemberServiceImpl.hello(String), arg = helloA

 

 

 

다음은 args 지시자를 이용하는 방법이다.

@Around("allMember() && args(arg, ..)")
public Object logArgs2(ProceedingJoinPoint joinPoint, Object arg) throws Throwable {
    log.info("signature = {}, arg = {}" , joinPoint.getSignature(), arg);
    return joinPoint.proceed();
}

args(arg,..)에서의 arg이름과 public Object logArgs2(ProceedingJoinPoint joinPoint, Object arg)이 동일해야 한다. 

signature = String hello.aop.member.MemberServiceImpl.hello(String), arg = helloA

 

 

다음에는 더 깔끔하게 해 보자.

 

@Before("allMember() && args(arg, ..)")
public void logArgs3(JoinPoint joinPoint, String arg) throws Throwable {
    log.info("3th signature = {}, arg = {}" , joinPoint.getSignature(), arg);
}
3th signature = String hello.aop.member.MemberServiceImpl.hello(String), arg = helloA

 

 

 

이번에는 호출된 객체를 받아보자.

 

@Before("allMember() && this(obj)")
public void logArgs4(JoinPoint joinPoint, MemberService obj) throws Throwable {
    log.info("4th signature = {}, obj = {}" , joinPoint.getSignature(), obj.getClass());
}

@Before("allMember() && target(obj)")
public void logArgs5(JoinPoint joinPoint, MemberService obj) throws Throwable {
    log.info("5th signature = {}, obj = {}" , joinPoint.getSignature(), obj.getClass());
}

 

this와 target의 차이점은 다음 로그를 보자.

4th signature = String hello.aop.member.MemberServiceImpl.hello(String), obj = class hello.aop.member.MemberServiceImpl$$EnhancerBySpringCGLIB$$5b4019ac
5th signature = String hello.aop.member.MemberServiceImpl.hello(String), obj = class hello.aop.member.MemberServiceImpl

 

this는 스프링 컨테이너에 올라가 있는 Proxy객체를 반환하는 반면, target은 실제 구현체를 반환해주었다. 

상황에 따라 Proxy객체가 필요한지 실 구현체가 필요한지에 따라 골라서 사용할 수 있다.

 

 

@target, @within, @annotation을 통해 애노테이션 정보를 가져오고 애노테이션의 들어있는 값을 꺼낼 수도 있다.

 

@Before("allMember() && @target(annotation)")
public void logArgs6(JoinPoint joinPoint, ClassAop annotation) throws Throwable {
    log.info("6th signature = {}, annotation = {}" , joinPoint.getSignature(), annotation);
}

@Before("allMember() && @within(annotation)")
public void logArgs7(JoinPoint joinPoint, ClassAop annotation) throws Throwable {
    log.info("7th signature = {}, annotation = {}" , joinPoint.getSignature(), annotation);
}

@Before("allMember() && @annotation(annotation)")
public void logArgs8(JoinPoint joinPoint, MethodAop annotation) throws Throwable {
    log.info("8th signature = {}, annotation value = {}" , joinPoint.getSignature(), annotation.value());
}
6th signature = String hello.aop.member.MemberServiceImpl.hello(String), annotation = @hello.aop.member.annotation.ClassAop()
7th signature = String hello.aop.member.MemberServiceImpl.hello(String), annotation = @hello.aop.member.annotation.ClassAop()
8th signature = String hello.aop.member.MemberServiceImpl.hello(String), annotation value = test Value

 

this : 스프링 빈객체

target : Target 객체

 

이 둘은 적용 타입 하나를 정확하게 지정해야 한다.

 

반응형

'Spring|Spring-boot > Spring AOP' 카테고리의 다른 글

Spring AOP 한계(2)  (0) 2022.10.14
Spring AOP 한계  (0) 2022.01.31
Spring AOP @target, @within  (0) 2022.01.29
Pointcut - within, args  (0) 2022.01.29
Pointcut - execution  (0) 2022.01.29

댓글