티스토리 뷰

RetentionPolicy와 AOP에 대한 고찰

관심을 가지게 된 이유

'땅콩' 프로젝트에서 쿠키를 통한 세션 관리 로직을 AOP로 리팩터링 하도록 결정하고 이를 구현하였다.
이 과정에서 AspectJ를 활용하여 AOP를 구현하였다.

@IssueCookie라는 커스텀 애노테이션을 만들어 해당 애노테이션이 있는 경우 비즈니스 로직 호출이 완료된 이후 쿠키를 발급하는 로직이 호출되도록 설정하였다.


의문점 발생

문제 상황

나는 ‘비즈니스 로직 호출 전에 애노테이션이 있는지 확인하는 과정’이 있기에 런타임까지 애노테이션에 대한 정보가 있어야 한다고 생각했다.
그래서 해당 커스텀 애노테이션의 RetentionPolicyRUNTIME으로 설정했다.
하지만 CLASS로 바꿔도 기능이 아무 문제 없이 동작했다.
이에 대한 의문이 생겨서 찾아보게 되었다.


RetentionPolicy란?

RetentionPolicy는 애노테이션이 어느 시점까지 유지될지(라이프 사이클)를 결정하는 것이다.
자원을 효율적으로 관리하고 애노테이션의 의도를 전달하기 위해 사용한다.
이를 설정하지 않으면 애노테이션이 불필요하게 유지되거나, 필요한 시점에 접근할 수 없다.

RetentionPolicy 옵션

  • SOURCE: 소스 코드까지만 남아있다.
  • CLASS: 클래스 파일(바이트 코드)까지만 남아있다.
  • RUNTIME: 런타임까지 남아있다.

위빙과 RetentionPolicy

RetentionPolicy 값은 위빙(Weaving)과 관련이 깊은 설정 값인 것 같다.
위빙(Weaving)은 애플리케이션 코드의 적절한 위치에 Aspect를 적용하는 과정을 말한다.
쉽게 말해, 부가 기능이 애플리케이션 코드에 추가되는 과정이다.
위빙 시점에 따라 다음과 같이 나뉜다.

  • Compile time weaving (CTW): 컴파일 시점
  • Load time weaving (LTW): 클래스 로드 시점
  • Runtime weaving (RTW): 런타임

RetentionPolicy 옵션과 유사한 점이 있다.

  • 컴파일 시 위빙: 애노테이션이 SOURCE까지만 남아 있으면 충분하다.
  • 클래스 로드 시 위빙: 애노테이션이 CLASS까지만 남아 있으면 충분하다.
  • 런타임 위빙: 애노테이션이 RUNTIME까지 남아 있어야 한다.

AOP 개념 다시 살펴보기

AspectJSpring AOP를 혼동하고 있었다. 둘은 전혀 다른 것이다.
이를 이해하기 위해 AOP에 대해 자세히 정리하였다.

AOP란?

AOP는 Aspect-Oriented Programming의 약자로, 애플리케이션의 핵심 기능과 부가 기능을 분리하여 Aspect라는 별도의 모듈로 설계하는 방법을 말한다.

  • 부가 기능 모듈을 Aspect라고 부른다.
  • AOP는 크게 정적 AOP동적 AOP로 나뉜다.
  • 위빙 시점에 따라 나뉜다.

정적 AOP

  • 컴파일 타임 및 로드 타임에 위빙
  • 대표적으로 AspectJ

동적 AOP

  • 런타임에 위빙
  • Spring AOP는 동적 AOP이며 프록시 기반으로 런타임에 동작한다.

그래서 왜 내 코드는 CLASS일 때 동작할까?

나는 AspectJ로 쿠키 로직을 구현했는데, AspectJ는 컴파일 타임 위빙과 로드 타임 위빙으로 동작한다는 것을 알게 되었다.
따라서 RetentionPolicy를 RUNTIME으로 설정하지 않아도 된다는 점은 이해되었다.

그렇다면 RetentionPolicy를 SOURCE로 설정해도 동작할까?


아쉽게도 그렇지 않았다.

이유

Maven/Gradle로 다운받은 라이브러리(jar 파일)에는 소스 코드가 포함되지 않는다.
따라서 SOURCE 정책을 사용하면 컴파일된 라이브러리에는 애노테이션 정보가 남아있지 않아 동작하지 않는다.


결론

아직 내 역량으로는 100% 이해하지는 못했지만, AspectJ로 구현한 로직에서는 RetentionPolicy를 CLASS로 설정해야 한다는 점은 명확히 이해했다.
라이브러리에서 활용할 경우에도 SOURCE가 아닌 CLASS 정책으로 설정해야 한다.
뭔가 찜찜한 결론을 낸 것 같아 아쉽지만, 나중에 더 알게 되는 내용이 있다면 추가해보겠다.