Back-end/Spring

[Spring] AOP 내부 메서드 호출 방법

shoney9254 2023. 3. 12. 16:46
반응형

AOP 내부 메서드 호출 방법

 

1. 문제 상황

프로젝트에서 AOP를 사용해서 메서드들을 로그로 남겨야 하는 상황이었습니다. 제가 로그로 남겨야 하는 메서드는 외부로 노출된 메서드가 아닌, 외부로 노출된 메서드가 호출하는 내부 메서드입니다.

하지만 AOP는 클래스의 외부함수만 호출됩니다.

 

1-1. 상황 재연

아래 소스와 같이 외부 메서드가 있고, 외부 메서드가 호출하는 내부 메서드가 있습니다.

저는 외부, 내부 메서드 모두 AOP를 사용해야 했습니다.

 

1-1-1. 서비스 클래스

@Slf4j
@Service
public class DeanService {
    public void externalMethod(String input) {
				log.info("외부 메서드 시작");
        internalMethod(input);
				log.info("외부 메서드 완료");
    }

    public void internalMethod(String input) {
				log.info("내부 메서드 시작");
				log.info(input);
				log.info("내부 메서드 완료");
    }
}

1)externalMethod : 클래스 외부에서 호출되는 메서드 (AOP 대상)

2)internalMethod : 클래스 내부에서 호출되는 메서드 (AOP 대상)

 

1-1-2. Advice 클래스 : AOP를 사용하는 클래스입니다.

@Slf4j
@Aspect
public class DeanAdvice {
    @Around("execution(* hello.aop.order.DeanService.externalMethod(..))")
    public void aopExternal(ProceedingJoinPoint joinPoint) throws Throwable {
				log.info("AOP 외부 메서드 실행");
        joinPoint.proceed();
				log.info("AOP 외부 메서드 종료");
    }

    @Around("execution(* hello.aop.order.DeanService.internalMethod(..))")
    public void aopInternal(ProceedingJoinPoint joinPoint) throws Throwable {
				log.info("AOP 내부 메서드 실행");
        joinPoint.proceed();
				log.info("AOP 내부 메서드 종료");
    }
}

1)aopExternal : DeanService 외부 메서드를 포인트 컷 해서 사용하는 AOP메서드 입니다. DeanService 외부 메서드 가 실행하기 전/후 로 로그를 작성합니다.

2)aopInternal : DeanService 내부 메서드를 포인트 컷 해서 사용하는 AOP메서드 입니다. (문제가 발생할 메서드) DeanService 내부 메서드 가 실행하기 전/후 로 로그를 작성합니다.

 

1-2. 결과

콘솔 로그를 보면 내부 메서드에는 AOP가 실행되지 않는 것을 확인 할 수 있습니다.

 

2. 해결 방안

2-1. 자기 자신을 주입 + @Lazy 사용 : 지연 주입

@Service
public class DeanService {
    @Lazy
    @Autowired
    DeanService deanService;

    public void externalMethod(String input) {
				log.info("외부 메서드 시작");
        deanService.internalMethod(input);
				log.info("외부 메서드 완료");
    }

    public void internalMethod(String input) {
				log.info("내부 메서드 시작");
				log.info(input);
				log.info("내부 메서드 완료");
    }
}

@Autowired : DeanService를 @Autowired로 또 생성합니다. Lazy를 하지 않으면, 순환참조 오류 발생합니다.

 

2-2. 자기 자신을 주입하지 않도록 새로운 클래스를 구현

너무 허무한 해결 방법이라고 생각할 수 있다고 생각합니다. 하지만, AOP를 사용하기 위해서 인터페이스를 하는 외부 메서드를 따로 클래스 분리하는 것도 해결 방법중에 하나입니다.

 

 

<참조사이트>

스택오버플로우의 내용을 참조해서 만들었습니다.

https://stackoverflow.com/questions/13564627/spring-aop-not-working-for-method-call-inside-another-method

 

Spring AOP not working for method call inside another method

There are two methods defined in ABC.java public void method1(){ ......... method2(); ........... } public void method2(){ ............... ............... } I want to have AOP on c...

stackoverflow.com

 

반응형