[Spring Boot] 구조분석 (6) - Custom Annotation 개념(@interface)
- 개요
안녕하세요. 이번 시간에는 Annotation의 대해 알아보겠습니다.
Java로 개발을 하다 보면 해당 Annotataion을 볼 수 있습니다. 간혹 @Orerride Annotation을 보실 수 있습니다.
@Orerride의 대해 모르시는 분들은 아래 링크를 통해 학습하고 오시는 걸 추천드리겠습니다.
[Java] 오버로딩(Overloading)과 오버라이딩(Overriding) 개념 및 사용법
- 개념
Java라는 언어는 기본적으로 내장된 Annotation이 존재합니다.
패키지는 기본적으로 아래 패키지로 시작됩니다.
package java.lang;
1. @Override
- 부모(상위) 클래스 또는 인터페이스에서 정의한 메서드를 자식(하위) 클래스가 재정의해서 사용하는 기술
2. @Deprecated
- 말 그대로 해당 Annotation이 선언된 코드는 더 이상 사용하지 않는다고 명시적으로 표시할 때 사용합니다.
3. @SuppressWarnings
- 해당 Annotation이 선언된 곳은 컴파일 경고를 무시하도록 합니다.
4. @SafeVarargs
- 해당 Annotation은 Java 7부터 지원되는 Annotation이며, 제너릭과 같은 가변인자의
5. @FuncationalInterface
- Java 8부터 지원하며, 함수형 인터페이스를 정의할 때 사용되는 Annotation입니다.
- 만약의 메서드가 존재하지 않거나, 1개 이상의 메서드(default, static 메서드는 제외)가 존재할 경우 컴파일 오류를 발생시킵니다.
만약 잘못 정의했을 때 아래와 같음 메시지가 나타납니다.
Multiple non-overriding abstract methods found in interface...
자 그럼 @Orerride Annotation 내부를 확인해 보겠습니다.
package java.lang;
import java.lang.annotation.*;
...
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
엄청 이상한 코드들이 많이 있는 걸 확인할 수 있습니다. 그리고 패키지가 조금 다릅니다.
import java.lang.annotation.*;
Annotation을 만들때 기본적으로 다른 Annotation을 사용합니다.
1. @Retention
- 컴파일 시 Annotation을 어느 시점까지 유지할 것인지 결정합니다.
- RetentionPolicy라는 값을 전달 받는데 RetentionPolicy는 무엇일까요?
package java.lang.annotation;
...
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
- RetentionPolicy란
package java.lang.annotation;
...
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
* 해당 어노테이션은 컴파일러에서 삭제해야한다.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*
* 해당 Annotation은 컴파일러에 의해 클래스 파일을 기록되지만, 런타임 환경 VM이 해당 클래스를 보유할 수 없다.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*
* 해당 Annotation은 컴파일러에 의해 클래스 파일을 기록되고 런타임 환경 VM에 의해 유지됩니다.
*
*/
RUNTIME
}
결국 해당 클래스가 유지되는 상황을 정의합니다. 자세한 설명은 주석을 확인하시면 좋을 것 같아요!
2. @Target
- 해당 Annotation은 우리가 사용하고 싶은 곳을 정의합니다. 무슨 말이냐면 변수 필드, 메서드, 생성자 등과 같이 선언 가능 범위를 지정할 때 사용합니다.
package java.lang.annotation;
...
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
기본 값으로 ElementType 클래스를 여러개 받습니다.
package java.lang.annotation;
...
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE
}
- 종류는 다음과 같습니다.
- ElementType.TYPE : 타입 선언
- ElementType.FIELD : 멤버 변수 선언
- ElementType.METHOD : 메서드 선언
- ElementType.PARAMETER : 전달인자 선언
- ElementType.CONSTRUCTOR : 생성자 선언
- ElementType.LOCAL_VARIABLE : 지역 변수 선언
- ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
- ElementType.PACKAGE : 패키지 선언
- ElementType.TYPE_PARAMETER : 전달인자 타입 선언
- ElementType.TYPE_USE : 타입 선언 (Java 1.8)
- ElementType.MODULE : 모듈 선언 (Java 9)
3. @Inherited
- Annotation 간의 상속을 가능하게 합니다.
4. @Documented
- 해당 Annotation을 Javadoc에 포함 시킵니다.
5. @Repeatable
- Java 8 부터 지원하며, 연속적으로 Annotation을 선언할 수 있게 합니다.
이번 시간에는 Custom Annotation에 대해 알아봤습니다. Custom Annotation을 실제 만들고 적용하는 부분은 추후 포스팅에 기재하겠습니다.