개요

스프링을 안지 어언 햇수로 3년이 넘어간다. 하지만 애노테이션을 잘 모른다. 하하 

  • 해당 글은 여기 링크글을 기본 골자로 삼아 해석을 진행하고, 추가적인 내용은 참고링크로 걸어두었습니다.

 

설명

  • 소스코드에 메타데이터를 삽입할 수 있는 기법이다. 
  • 자바 5 부터 등장하였다.
@Retention(RetentionPolicy.RUNTIME)         // (1)
@Target(ElementType.TYPE)                   // (2)
@Inherited                                  // (3)
@Documented                                 // (4)
public @interface CustomAnnotation {        // (5)
    String name() default "";               // (6)
    int value();                            // (7)
}
  • @Retention
    • 코드의 라이프사이클(수명주기) 를 나타낸다. (주석이 유지되는 수명을 뜻함)
  • @Target
    • 주석을 사용할 수 있는 곳을 나타낸다.
  • @Inherited
    • 존재 시, 해당 타입은 하위 서브 타입에 전달된다.
  • @Document
    • 존재 시, javadoc 과 같은 문서화 도구에 접근할 수 있다. (존재하여야 필드 값 호출이 가능)
  • @interface
    • 애노테이션 임을 명시적으로 나타낸다.
  • (6) ~ (7)
    • 선택적으로 기본값이 있는 주석의 값이다.

 

애노테이션을 작성한다면 우리가 만든 클래스에 해당 애노테이션을 아래와 같이 붙일 수 있다.

@CustomAnnotation(name = "custom", value = Integer.MAX_VALUE)
public class CustomType {

}

 

@Retention

코드의 라이플사이클은 아래와 같다.

source code -> (compiler) -> class file -> (JVM) -> runtime

Retention Policy 의 애노테이션은 코드 라이프사이클을 반영하고 있으며, 메타데이터의 사용할 수 있는 방법을 제공하고 있다.

  • @RetentionPolicy.SOURCE
    • 해당 애노테이션은 소스코드인 경우에만 가용된다. 컴파일러는 해당 메타데이터 정보를 사용하지 않을 뿐만 아니라 런타임에서도 접근할 수 없다. 
    • 해당 애노테이션은 pre-compile 툴에 적합하다. (annotation processor 와 같은 것들에 유용)
  • @RetentionPolicy.CLASS
    • 해당 애노테이션은 디폴트 애노테이션이다. 컴파일러는 해당 애노테이션에 접근할 수 있다. 컴파일되고 class file 에서 가용된다. 하지만 런타임 환경에서는 가용되지 않는다.
    • 해당 애노테이션은 post-compiler byte code 툴에서 사용될 수 있다.
  • @RetentionPolicy.RUNTIME
    • 해당 애노테이션은 런타임에서 가용된다.

 

@Target

모든 애노테이션이 모든 Target 에 대해서 의미가 있는 것이 아니다. 따라서 허용이 가능한 Target을 명시적으로 선정 해야한다. 8가지의 Target 설정이 정의된다. (링크)

  • ElementType.PACKAGE
  • ElementType.TYPE
  • ElementType.TYPE_PARAMETER
  • ElementType.TYPE_USE
  • ElementType.ANNOTATION_TYPE
  • ElementType.CONSTRUCTOR
  • ElementType.FIELD
  • ElementType.METHOD
  • ElementType.LOCAL_VARIABLE
// 단일 Target 설정 가능하다.
@Target(ElementType.FIELD)
public @interface CustomTargetAnnotation {
    
}

// 다중 Target 설정도 가능하다.
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
public @interface CustomTargetAnnotation {

}

만일 @Target 이 설정되지 않았다면, ElementType.TYPE_PARAMETER 를 제외하고는 나머지는 다 허용인 상태이더라.

 

@Documented

메타데이터 및 그 값에 액세스 할 수 있도록 해준다.

 

설명은 여기까지하고, 직접 이건 실습이 필요하다.

 

내가 해본 결과 애노테이션은 손쉽게 메타데이터 형태를 삽입이 가능하도록 해주었는데, 자바의 리플렉션 API 를 기반으로 한다. 내가 흔하게 쓰는 롬복인 경우에는 annotation processor 에 대한 추가적인 설정이 필요한 듯 하다. 그 기반 역시도 리플렉션이 들어가있다.

 

리플렉션 기법을 이용하게 된다면, 컴파일단계가 아닌 런타임단계에서 코드를 제어가 가능하게 된다.

 

하물며, 스프링부트는 어떠할까?

 

스프링부트 또한 현재 애노테이션기반으로 빈을 설정하고 설정된 빈은 스프링이 실행되면서 IoC 컨테이너에 의해 등록되버린다. 이 때, 해당 빈들을 등록하는 시점에서도 리플렉션 기법이 들어가고, 스프링부트 설정 상 수많은 애노테이션들 또한 그 기반은 리플렉션 API 의 이용이다.

 

참고자료

Posted by doubler
,