[JAVA] @Retention 어노테이션 알아보기
@Retention 어노테이션은 다른 어노테이션을 정의할 때 사용되며 해당 어노테이션의 라이프 사이클 즉, 어떤 시점까지 유지되는 지를 정한다.
@Retention 어노테이션은 다음과 같이 세 가지 속성을 가지고 있다.
- RetentionPolicy.SOURCE
- RetentionPolicy.CLASS
- RetentionPolicy.RUNTIME
RetentionPolicy.SOURCE
이 속성은 어노테이션을 컴파일 시간까지만 유지시키게 하며 컴파일된 클래스 파일에는 포함되지 않는다.
대표적으로 lombok의 @Getter, @Setter 의 경우가 이 속성을 사용하고 있다.
@Getter, @Setter 의 경우 런타임 단계에서 특정한 작업을 위한 어노테이션이 아닌 단순 코드 생성을 도와주기 위한 어노테이션이기 때문에 실제 컴파일 단계에서 getter, setter 코드가 바이트 코드로 생성되어 포함된다.
따라서 바이트 코드에 이미 getter, setter 코드가 포함되어 있기 때문에 어노테이션 정보를 유지할 필요가 없어 컴파일 단계까지만 어노테이션을 유지시키는 RetentionPolicy.SOURCE 속성을 사용하는 것이다.
실제 바이트 코드를 디컴파일 해보면 @Getter, @Setter 어노테이션은 사라졌지만 getter, setter 메소드가 생성된 것을 확인할 수 있을 것이다.
RetentionPolicy.CLASS
속성을 명시하지 않을 시 정해지는 기본값이며, 이 속성은 컴파일된 클래스 파일에는 포함되지만, 실행 시간에는 유지되지 않는 속성이다.
따라서 리플렉션을 사용하여 런타임에 해당 어노테이션을 읽을 수 없다.
대표적으로 Maven/Gradle 로 다운받은 라이브러리와 같이 jar 형태의 파일 소스에서 많이 사용된다.
이미 바이트 코드로 변환된 jar 파일 소스의 경우 .SOURCE 속성을 사용하면 어노테이션 정보가 남아있지 않기 때문에 다른 부가적인 어노테이션 기능들을 사용하기 위해 .CLASS 를 사용한다.
RetentionPolicy.RUNTIME
이 속성은 컴파일된 클래스 파일에 포함되고, 런타임 시간에도 유지되게 한다.
따라서 리플렉션을 사용하여 런타임에 해당 어노테이션을 읽고 처리할 수 있다. 대표적으로 @Controller, @Service, @Autowired 등 스프링이 실행중인 시점에 컴포넌트 스캔이 가능해야 하는 경우, 또는 @Transactional 어노테이션과 같이 런타임에 트랜잭션을 관리해야 하는 경우에 사용된다.