본문 바로가기

Java

Live Study _ 12주차. Annotation

<학습 목표>

1. Annotation 정의하는 방법

2. @retention

3. @target

4. @documented

5. Annotation Processor 


1. Annotation 정의 : 

AnnotationMetadata라고 볼 수 있다.

Metadata란 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서

코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보이다. 

 

Annotation은 3가지 용도로 사용된다.

1. 컴파일에게 코드 문법 에러를 체크하도록 정보 제공
2. 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
3. 실행 시 특정 기능을 실행하도록 정보 제공 

 

예) 

컴파일에게 코드 문법 에러를 체크하도록 정보를 제공하는 대표적인 예시로는 @Override 

annotation이다. @Override 메소드 선언 시 사용하는데, 메소드가 재정의 된 것임을 컴파일러에게

알려주어 컴파일러가 재정의 검사를 하도록 도와준다. 

 

정의 방법 : 

Annotation 타입을 정의하는 방법은 interface를 정의하는 것과 유사하다. 

예) public @interface AnnotationName {   }

Annotation은 기본 element인 value를 가질 수 있다. 

예) public @interface AnnotationName {

String value();

int elementName() default 5;

}

 

Annotation 적용 대상 :

ElementType 열거상수 적용 대상
TYPE 클래스, 인터페이스, 열거 타입
ANNOTATION_TYPE 어노테이션
FIELD 필드
CONSTRUCTOR 생성자
METHOD 메소드
LOCAL_VARIABLE 로컬변수
PACKAGE 패키지

Annotation을 적용할 수 있는 대상은 java.lang.annotation.ElementType 열거 상수이다. 

 


2. @target :

Annotation이 적용될 대상을 지정할 때에는 @target Annotation을 사용한다. 

@target의 기본 element인 value는 ElementType 배열을 값으로 가진다. 

이것은 Annotation 적용될 대상을 복수개로 지정하기 위해서다. 

예시

3. @retention :

- Annotation 유지 정책 :

Annotation 정의 시 한 가지 더 추가해야 할 내용은 사용 용도에 따라

@AnnotationName을 어느범위까지 유지할 것인지 지정해야 한다. 

예를 들어, 소스상에만 유지할 건지, 컴파일된 클래스까지 유지할 건지,

런타임 시에도 유지할 건지를 지정해야 한다. 

Annotation 유지 정책은 java.lang.annotation.RetentionPolicy 열거 상수로 정의되어 있다.

RetentionPolicy 열거 상수 설명
SOURCE 소스상에만 annotation 정보 유지. 소스 코드 분석할 때만 의미가 있고 바이트 코드 파일에는 정보가 남지 않는다. 
CLASS 바이트 코드 파일까지 annotation 정보 유지. 하지만 리플렉션을 이용해서 annotation 정보를 얻을 수 없다. 
RUNTIME 바이트 코드 파일까지 annotation 정보 유지. 리플렉션을 이용해서 런타임 시에 annotation 정보를 얻을 수 있다.

* Reflection이란 runtime 시에 class의 meta 정보를 얻는 기능을 말한다. 

예를 들어, class가 가지고 있는 field가 무엇인지, 어떤 생성자를 갖고 있는지, 어떤 method를 가지고 있는지 

적용된 annotation 무엇인지 알아내는 것이 Reflection이다. 

예시

Reflection을 이용해서 런타임 시에 annotation 정보를 얻으려면 유지 정책을 runtime으로 설정. 

 

- runtime 시 annotation 정보 사용하기 :

annotation 자체는 아무런 동작을 가지지 않는 단지 표식일 뿐이지만, reflection을 이용해서

annotation의 적용 여부와 element 값을 읽고 적절히 처리할 수 있다. 

리턴 타입  메소드명(매개변수) 설명
Field[ ] getFields( ) 필드 정보를 Field 배열로 리턴
Constructor[ ]  getConstructors( )  생성자 정보를 Constructor 배열로 리턴
Method[ ]  getDeclaredMethods( )  메소드 정보를 Method 배열로 리턴

Field, Constructor, Method에 적용된 annotation 정보를 얻으려면 Class의 다음 메소드를

통해서 java.lang.reflect 패키지의 Field, Constructor, Method 타입의 배열을 얻어야 함. 

 

예시

(위에 예시는 메소드의 실행 내용을 구분선으로 분리해서 콘솔에 출력하도록 하는 PrintAnnotation이다.)

 

@target은 method에만 적용하도록 했고, @retention은 runtime 시까지 annotation 정보를 유지하도록 한다.

기본 element value는 구분선에 사용될 문자이고, number는 반복 출력 횟수이다. 

각각 default 값으로 "-" 와 15를 줌. 

 

예시

위 예시는 reflection을 이용해서 Service 클래스에 적용된 annotation 정보를 읽고

element 값에 따라 출력할 문자와 출력 횟수를 콘솔에 출력한 후 해당 메소드를 호출하는 것이다. 

 

4. @documented : 

음... 열심히 뒤져 보았지만 머리에 딱 꽂히지 않는다...

Meta annotation 중 하나이고 적용된 annotation에 대한 정보를 javadoc에 나타내는 Annotation이라고 한다...

 

5. Annotation Processor :

이것은 자바 컴파일러 플로그인 중 하나로 annotation에 대한 정보와 검사, 생성, 수정하는 역할을 한다.