백앤드(Back-End)/Spring Boot

[Spring Boot] 구조분석 (6) - Custom Annotation 개념(@interface)

RyanSin 2023. 5. 1. 02:52
반응형

- 개요

안녕하세요. 이번 시간에는 Annotation의 대해 알아보겠습니다.

 

Java로 개발을 하다 보면 해당 Annotataion을 볼 수 있습니다. 간혹 @Orerride Annotation을 보실 수 있습니다. 

 

@Orerride의 대해 모르시는 분들은 아래 링크를 통해 학습하고 오시는 걸 추천드리겠습니다.

[Java] 오버로딩(Overloading)과 오버라이딩(Overriding) 개념 및 사용법

 

[Java] 오버로딩(Overloading)과 오버라이딩(Overriding) 개념 및 사용법

- 지난 시간 안녕하세요. 지난 시간에는 클래스 상속에 대해 알아봤습니다. 혹시 놓치신 분들은 아래 링크를 통해 상속에 대한 개념을 학습하고 오시는 걸 추천드리겠습니다. any-ting.tistory.com/31 [

any-ting.tistory.com

 

- 개념

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을 실제 만들고 적용하는 부분은 추후 포스팅에 기재하겠습니다.