본문 바로가기
Engineering WIKI/Docs

@Retention 어노테이션 개념 뿌수기 (RetentionPolicy SOURCE vs CLASS vs RUNTIME)

by wonos 2023. 8. 17.

핵심 요약

  • Retention ⇒ ‘보유’를 뜻 하는 명사
    • SOURCE: 소스코드까지만 유지 (즉, 컴파일 과정에서 어노테이션 정보는 사라짐)
    • CLASS: 클래스파일 까지만 유지 (런타임시 유지안됨)
    • RUNTIME: 런타임 시점까지 유지 (Reflection API 로 어노테이션 정보 조회 가능)@Retention 어노테이션은 어노테이션의 라이프 사이클 / 즉, 어노테이션이 언제까지 살아 남아 있을지를 정하는 것입니다.

  • SOURCE 정책
    • Java → Class파일로 변환시 삭제되고, 실제 동작하는 소스로 변경 됨. lombok의 Getter/Setter등이 해당 됨.
    • Class로 파일로 변환 시 Getter/Setter 어노테이션은 실제 get(), set() 메소드로 치환되고 사라짐.
  • RUNTIME 정책
    • 서비스 중, 서버 기동 중에도 해당 어노테이션은 유지 됨. @Controller, @Service, @Autowired 등이 있습니다. 스프링이 올라오는 실행 중인 시점에 컴포넌트 스캔이 가능해야하기 때문에 RUNTIME 정책이 필요합니다. (스프링도 내부적으로 Reflection 등을 활용하여 어노테이션이 붙은 놈들만 가져옵니다.)
  • CLASS 정책
    • 박종훈님의 설명
      • 인텔리제이를 써보셨다면, @NonNull 등이 붙어있는 경우 null 값을 넣게되면 노랑색 경고로 알려줍니다.
      • "아니 그러면 SOURCE로 해도 될거 같은데?" 싶으실텐데요, 중요한점은 Maven/Gradle로 다운받은 라이브러리와 같이 jar 파일에는 소스가 포함되어있지 않다는 점입니다. class 파일만 포함되어있죠 (Download Sources 옵션은 논외로 할께요)
      • 즉, class 파일만 존재하는 라이브러리 같은 경우에도 타입체커, IDE 부가기능 등을 사용할수 있으려면 CLASS 정책이 필요하게 됩니다. SOURCE 정책으로 사용한다면 컴파일된 라이브러리의 jar 파일에는 어노테이션 정보가 남아있지 않기 때문이죠.
      • 그외에도 클래스 로딩시 무언가를 하고 싶은 경우에도 사용 될 수 있다.

자바 리플렉션 (Reflection)

  • JVM은 클래스 정보를 클래스 로더를 통해 읽어와서 해당 정보를 JVM 메모리에 저장한다. 그렇게 저장된 클래스에 대한 정보가 마치 거울에 투영된 모습과 닮아있어, 리플렉션이라는 이름을 가지게 되었다.
  • 리플렉션을 사용하면 생성자, 메소드, 필드 등 클래스에 대한 정보를 아주 자세히 알아낼 수 있다.