Spring AOP Pointcut 표현식 - Advice 에 매게변수 전달

목차

Advice 에 매게변수 전달

포인트 컷 포현식을 사용해서 AOP 가 적용되는 객체나 메소들의 정보를 Advice 내 매개변수로 정보들을 전달 할 수 있습니다.

Advice 로 매개변수로 정보들을 넘기기 위해서는 포인트컷의 이름과 매개변수 이름이 같아야 합니다. 또한, 값이 들어올때 타입이 매개변수에서 정의한 타입으로 제한이 됩니다.

AOP 적용 확인을 위한 테스트 코드

@Autowired
MemberService memberService;

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

메소드 매개변수값 정보를 Advice 에 전달

args 를 이용하면 메소드에 전달된 매개변수의 값 정보를 가져올 수 있습니다.

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


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

// 매게변수 값을 전달 받을 수 있습니다.
@Around("allMember() && args(arg,..)")
public Object logArgs2(ProceedingJoinPoint joinPoint, Object arg) throws Throwable {
log.info("[logArgs2]{}, arg={}", joinPoint.getSignature(), arg);
return joinPoint.proceed();
}

@Before("allMember() && args(arg,..)")
public void logArgs3(String arg) {
log.info("[logArgs3] arg={}", arg);
}
2024-11-28 12:28:56.888  INFO 85888 --- [    Test worker] h.a.p.ParameterTest$ParameterAspect      : [logArgs1]String hello.aop.member.MemberServiceImpl.hello(String), arg=helloA
2024-11-28 12:28:56.889 INFO 85888 --- [ Test worker] h.a.p.ParameterTest$ParameterAspect : [logArgs2]String hello.aop.member.MemberServiceImpl.hello(String), arg=helloA
2024-11-28 12:28:56.889 INFO 85888 --- [ Test worker] h.a.p.ParameterTest$ParameterAspect : [logArgs3] arg=helloA

객체 정보를 Advice 에 전달

this 는 런타임 환경의 프록시 객체 정보를 가져오고, target 은 실제 대상 구현체 정보를 가져옵니다.

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


// this 는 런타임 환경의 프록시 객체 정보를 가져옵니다
@Before("allMember() && this(obj)")
public void thisArgs(JoinPoint joinPoint, MemberService obj) {
log.info("[this]{}, obj={}", joinPoint.getSignature(), obj.getClass());
}

// target 은 실제 대상 구현체 정보를 가져옵니다.
@Before("allMember() && target(obj)")
public void targetArgs(JoinPoint joinPoint, MemberService obj) {
log.info("[target]{}, obj={}", joinPoint.getSignature(), obj.getClass());
}
2024-11-28 12:28:56.889  INFO 85888 --- [    Test worker] h.a.p.ParameterTest$ParameterAspect      : [this]String hello.aop.member.MemberServiceImpl.hello(String), obj=class hello.aop.member.MemberServiceImpl$$EnhancerBySpringCGLIB$$bc2c3fa8
2024-11-28 12:28:56.889 INFO 85888 --- [ Test worker] h.a.p.ParameterTest$ParameterAspect : [target]String hello.aop.member.MemberServiceImpl.hello(String), obj=class hello.aop.member.MemberServiceImpl

어노테이션 정보를 Advice 에 전달

@target, @within, @annotation 은 클래스나 메소드에 적용된 어노테이션 정보를 가져오는데 사용할 수 있습니다.

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


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

@Before("allMember() && @within(annotation)")
public void atWithin(JoinPoint joinPoint, ClassAop annotation) {
log.info("[@within]{}, obj={}", joinPoint.getSignature(), annotation);
}

@Before("allMember() && @annotation(annotation)")
public void atAnnotation(JoinPoint joinPoint, MethodAop annotation) {
// @ MethodAop 내의 value 값을 꺼내올 수 있습니다.
log.info("[@annotation]{}, annotationValue={}", joinPoint.getSignature(), annotation.value());
}
2024-11-28 12:28:56.889  INFO 85888 --- [    Test worker] h.a.p.ParameterTest$ParameterAspect      : [@target]String hello.aop.member.MemberServiceImpl.hello(String), obj=@hello.aop.member.annotation.ClassAop()
2024-11-28 12:28:56.889 INFO 85888 --- [ Test worker] h.a.p.ParameterTest$ParameterAspect : [@within]String hello.aop.member.MemberServiceImpl.hello(String), obj=@hello.aop.member.annotation.ClassAop()
2024-11-28 12:28:56.889 INFO 85888 --- [ Test worker] h.a.p.ParameterTest$ParameterAspect : [@annotation]String hello.aop.member.MemberServiceImpl.hello(String), annotationValue=test value
Share