본문 바로가기
Java & Kotlin/Spring

[Spring] AOP Joinpoint의 getThis()와 getTarget()

by heekng 2022. 8. 20.
반응형

AOP Joinpoint의 getThis()와 getTarget()

김영한님의 Spring 고급편을 수강하면서 수강하시는 분의 질문을 보고 작성하는 포스팅입니다.

커뮤니티의 질문을 보면 aspectj의 joinPoint를 통해 조회한 getThis()와 getTarget()의 결과가 같다는 질문이 있습니다.

eclipse aspectJ doc을 확인해보면, getThis()의 경우 현재 실행중인 개체(proxy 객체)를 반환하고, getTarget()의 경우 대상 개체(class 객체)를 반환한다고 나와있습니다.

@Around("com.heekng.aop.order.aop.Pointcuts.orderAndService()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("joinPoint.getThis() = {}", joinPoint.getThis());
    log.info("joinPoint.getTarget() = {}", joinPoint.getTarget());
    return joinPoint.proceed();
}

문제는 해당 getThis()의 결과값과 getTarget() 결과값을 출력했을 때, 모두 동일한 OrderService의 객체를 나타냅니다.

joinPoint에 들어오는 객체는 Proxy가 적용되었기 때문에 getThis()에는 Proxy 객체가 나타나야 하고, 이 문제에 대한 해답은 간단합니다.

@Around("com.heekng.aop.order.aop.Pointcuts.orderAndService()")
public Object doTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
    log.info("joinPoint.getThis() = {}", joinPoint.getThis());
    log.info("joinPoint.getThis().getClass() = {}", joinPoint.getThis().getClass());
    log.info("joinPoint.getTarget() = {}", joinPoint.getTarget());
    log.info("joinPoint.getTarget().getClass() = {}", joinPoint.getTarget().getClass());
    return joinPoint.proceed();
}

바로 getClass()를 통한 결과값을 봐야 우리가 확인하기를 원하는 해당 객체의 클래스가 나타나는데요.

jdk 동적 프록시 또는 cglib 기술을 사용해 구현된 Proxy는 우리가 proxy를 적용하고자 하는 클래스와 동일한 형태를 띄고 있지만, 실행을 원하는 메서드 주변에 원하는 로직을 포함하고 있고, 프록시를 이용한 AOP는 클라이언트가 이용하려는 객체가 proxy가 적용된 객체인지, 적용되지 않은 객체인지 모르게 합니다.

때문에 getThis() 또는 getTarget()를 통해 직접 조회한 결과는 OrderService를 나타내고, getClass()를 확인해야 해당 객체가 프록시가 적용되었는지 아닌지 확인 가능합니다.

감사합니다.

반응형