티스토리 뷰
목표
자바의 애노테이션에 대해 학습하기
학습할 것
-
애노테이션 정의하는 방법
-
@retention
-
@target
-
@documented
-
애노테이션 프로세서
1. 애노테이션 정의하는 방법
애노테이션은 메타데이터라고 볼 수 있는데 메타데이터란 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보이다. 어노테이션은 다음과 같은 형태로 작성된다.
@AnnotationName
애노테이션의 경우 다음과 같이 세 가지 용도로 사용된다.
- 컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
- 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공
- 실행 시(런타임 시) 특정 기능을 실행하도록 정보를 제공
컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공하는 대표적인 예로는 @Override 애노테이션이 있다.
@Override는 메소드 선언 시 사용하며 메소드가 재정의된 것임을 컴파일러에게 알려 컴파일러가 오버라이드 검사를 하도록 해준다.
정확히 오버라이드가 되지 않았다면 컴파일러는 에러를 발생시키게 된다.
애노테이션은 빌드 시 자동으로 XML 설정 파일을 생성하거나, 배포를 위해 JAR 압축 파일을 생성할 때도 사용된다.
또한, 실행 시 클래스의 역할을 정의하기도 한다.
애노테이션을 정의하는 방법은 인터페이스를 정의하는 것과 유사한데 다음과 같이 정의하면 된다.
public @interface AnnotationName {
}
정의한 애노테이션의 경우 코드에서 다음과 같이 사용할 수 있다.
@AnnotationName
2. @retention
애노테이션 정의 시 한 가지 더 추가해야 할 내용은 사용 용도에 따라 @AnnotationName을 어느 범위까지 유지할 것인지 지정한다.
소스상에서만 유지할 것인지, 컴파일된 클래스까지 유지할 것인지, 런타임 시에도 유지할 것인지를 지정하는 것이다.
어노테이션 유지 정책은 java.lang.annotation.RetentionPolicy 열거 상수로 다음과 같이 정의되어 있다.
RetentionPolicy 열거 상수 | 설명 |
SOURCE | 소스상에서만 어노테이션 정보를 유지한다. 소스 코드를 분석할 때만 의미가 있고, 바이트 코드 파일에는 정보가 남지 않는다. |
CLASS | 바이트 코드 파일까지 애노테이션 정보를 유지한다. 하지만 리플렉션을 이용해 애노테이션 정보를 얻을 수 없다. |
RUNTIME | 바이트 코드 파일까지 애노테이션 정보를 유지한다. 리플렉션을 이용해 애노테이션 정보를 얻을 수 있다. |
※ 리플렉션(Reflection)
리플렉션이란 런타임 시에 클래스의 메타 정보를 얻는 기능으로 클래스가 가지고 있는 필드가 무엇인지, 어떤 생성자를 갖고 있는지, 어떤 메소드를 가지고 있는지, 적용된 애노테이션은 무엇인지 알아내는 것이다.
리플렉션을 이용해 런타임 시 애노테이션 정보를 얻으려면 애노테이션 유지 정책을 RUNTIME으로 설정해야 한다.애노테이션 유지 정책을 지정할 때 사용되는 것이 바로 @Retention 애노테이션이다.@Retention의 기본 엘리먼트인 value는 RetentionPolicy 타입으로 위 3가지 열거 상수 중 하나를 지정하면 된다.
코드 자동 생성 툴을 개발하지 않는 이상 우리가 작성하는 애노테이션은 대부분 런타임 시점에 사용하기 위한 용도로 만들어진다.런타임 유지 정책을 적용하여 설정한 코드는 다음과 같다.
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationName {
}
3. @target
자바 컴파일러가 애노테이션이 어디에 적용될지 결정하기 위해 사용한다. 선언 가능한 위치는 다음과 같다.
- ElementType.PACKAGE : 패키지 선언
- ElementType.TYPE : 타입 선언
- ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
- ElementType.CONSTRUCTOR : 생성자 선언
- ElementType.FIELD : 멤버 변수 선언
- ElementType.LOCAL_VARIABLE : 지역 변수 선언
- ElementType.METHOD : 메서드 선언
- ElementType.PARAMETER : 전달인자 선언
- ElementType.TYPE_PARAMETER : 전달인자 타입 선언
- ElementType.TYPE_USE : 타입 선언
[런타임 시 애노테이션 정보 사용하기]
애노테이션 자체는 아무런 동작을 가지지 않지만 리플렉션을 이용해 애노테이션의 적용 여부와 엘리먼트 값을 읽고 처리할 수 있다.
클래스에 적용된 애노테이션 정보를 얻기 위해 java.lang.Class를 이용하지만, 필드, 생성자, 메소드에 적용된 애노테이션의 정보를 얻기 위해 Class의 다음 메소드들을 통해 java.lang.reflect 패키지의 Field, Constructor, Method 타입의 배열을 얻어야 한다.
리턴 타입 | 메소드명(매개 변수) | 설명 |
Field[] | getFields() | 필드 정보를 Field 배열로 리턴 |
Constructor[] | getConstructors() | 생성자 정보를 Constructor 배열로 리턴 |
Method[] | getDeclaredMethods() | 메소드 정보를 Method 배열로 리턴 |
이후 Class, Field, Constructor, Method가 가지고 있는 다음 메소드를 호출해 적용된 애노테이션 정보를 얻는다.
4. @documented
해당하는 애노테이션을 Javadoc에 포함시키는 애노테이션이다.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface CustomAnnotation {
String testDocument();
}
5. 애노테이션 프로세서
자바 컴파일러 플로그인의 일종으로 애노테이션에 대한 코드베이스를 검사, 수정, 생성하는 역할을 하는 플러그인이다.
애노테이션 프로세서를 적재적소에 잘 활용한다면 개발자의 코드를 단순화시킬 수 있다.
[동작 구조]
1. 자바 컴파일러는 애노테이션 프로세서가 사용된다는 것을 알고 있는 상태에서 컴파일을 수행하게 된다.
2. 애노테이션 프로세서들이 각자 역할에 맞게 구현된 상태에서 실행되지 않은 애노테이션 프로세서를 실행한다.
3. 애노테이션 프로세서 내부에서 애노테이션에 대한 처리를 한다.
4. 자바 컴파일러가 모든 애노테이션 프로세서가 실행되었는지 검사하며 , 모든 애노테이션 프로세서가 실행되지 않은 경우 반복한다.
'Project > 자바 라이브 스터디' 카테고리의 다른 글
자바 라이브 스터디 #13 I/O (0) | 2021.03.05 |
---|---|
자바 라이브 스터디 #11 : Enum (0) | 2021.03.05 |
자바 라이브 스터디 #10 멀티쓰레드 프로그래밍 (0) | 2021.01.23 |
자바 라이브 스터디 #9 예외 처리 (0) | 2021.01.15 |
자바 라이브 스터디 #7 패키지 (0) | 2020.12.31 |