Annotation을 정의하는 방법


 

Annotation이란?

JDK 1.5에 추가된 기능으로 실제 코드에 직접적인 영향을 주지 않고, 해당 코드를 처리하는 ****Compiler , Interpreter 혹은 Runtime에서 JVM에게 처리를 위한 정보를 제공하는 것이 주목적이다.

 

Single-Value Annotation

단일 변수만을 갖는 Annotation을 말하며, 값을 명시하여 데이터를 전달할 수 있다.

@SuppressWarnings, @Retention, @Target...

 

Full Annotation

두 개 이상의 변수를 갖는 어노테이션으로 여러 데이터를 ", "를 기준으로 Key : value 형식으로 전달하게 된다. @Generated...

 

Marker Annotation과 Interface

구현할 메서드, 상수 필드가 존재하지 않는 Interface나 필드 변수가 존재하지 않는 Annotation을 명칭 하며, Compiler, Interpreter, JVM에게 어떠한 정보를 제공하는 용도로만 사용된다.

Cloneable, Serializable, Remote Interface or @Overide, @Native, @Nullable, @Documented...

 

 

Annotation 종류

Compile Time에서 정보를 제공하는 Annotation (: Compiler )

  • @Override : 상위 클래스의 메서드를 재정의하였음을 나타내는 Annotation이다. 상위 클래스에 해당 메서드가 존재하지 않는 경우 Compiler가 경고하는 기능을 제공한다.
  • @SuppressWarnings : 컴파일러가 경고하는 내용을 Ignore 할 때 사용하는 Annotation이다.
  • @Native : Native Code에 의해 참조되는 상수 필드에 적용하는 Annotation으로 JNI를 통해 (C, C++ code) Native Method가 호출된다.
  • @Generated : 소스 코드를 생성하는 도구에 의해서 해당 코드가 자동적으로 생성되었음을 나타내는 Annotation이다.

 

Load-Build Time에서 정보를 제공하는 Annotation (: Compiler )

  • @Nullable : parameter에 대해 Null을 허용함을 나타내는 Annotation이다. ( JSR 305 )

 

Runtime Time에서 정보를 제공하는 Annotation (: Reflection API)

  • @FunctionalInterface : JDK 8부터 추가된 Annotation으로 해당 Interface가 하나의 메서드만을 제공하는 함수형 인터페이스임을 나타내는 Annotation이다.
  • @Deprecated : 더 이상 지원하지 않는 기능임을 알려주는 Annotation이다.
  • @SafeVarargs : Generic과 같은 가변 인자 Parameter를 사용할 때 발생하는 경고를 ignore 하는 Annotation이다.
  • @Repeatable : 해당 Annotation을 반복적으로 사용할 수 있게 지원하는 Annotation이다.
  • @Inherited : Meta Annotation 중 하나로 써 적용된 대상 Annotation을 하위 Class, Interface에게 상속시키는 Annotation이다.
  • @Retention
  • @Target
  • @Documented

 

Custom Annotation 정의

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface SampleAnnotation {

        String name() default "";

}

 

 

@Retention

 

Meta Annotation 중 하나로써 적용된 대상 Annotation이 어느 시점까지 정보를 유지할 것인지 정의하는 Annotation이다.

 

 

RetentionPolicy 필드 변수

  • SOURCE : Annotation 정보가 Compile Time에서 사라진다.
  • CLASS : Annotation 정보가 Compiler에 의해 참조되고 Runtime 시점에선 사라지게 된다.
  • RUNTIME : Annotation 정보가 Runtime 시점에 JVM이나 Reflection API에 의해 참조 가능하다.

 

 

@Target

Meta Annotation 중 하나로써 적용된 대상 Annotation이 어느 위치에 적용될 수 있는지를 정의하는 Annotation이다.

 

 

ElementType 필드 변수

  • TYPE : Class, Interface 등의 Level에 선언 가능하다.
  • METHOD : 메서드에 선언 가능하다.
  • FIELD : Enum, 상수, Field 변수에 대해 선언 가능하다.
  • PARAMETER : 매개변수에 선언 가능하다.
  • CONTRUCTOR : 생성자 Type에 선언 가능하다.
  • LOCAL_VARIABLE : 지역 변수에 대해 선언 가능하다.
  • ANNOTATION_TYPE : Annotation에 선언 가능하다.
  • PACKAGE : 패키지에 선언 가능하다.

 

 

@Documented

Meta Annotation 중 하나로써 적용된 대상 Annotation에 대한 정보를 Javadoc에 나타내는 Annotation이다.

 

 

Annotation Processor

Compile 시점에서 정의된 Annotation을 분석하고 처리하기 위해 사용되는 API이다.

 

소스 코드를 구문 분석하여 나타나는 결과인 Abstract Syntax Tree를 조작하여 코드를 추가하거나, 설정 정보를 변경하거나, 컴파일 에러, 경고 등을 생성하기도 한다.

 

Annotation Processing Flow

  1. 자바 컴파일러에 의해 빌드가 시작된다.

  2. Annotation Processor들이 각각의 처리를 시작한다.

  3. 주석이 달린 Class, Method, Field를 찾는다.

  4. 발견된 부분들의 정보를 이용하여 코드를 생성, 검증한다. (Lombok 등의 코드 생성 시점)

  5. 생성된 정보, 코드, 문자열 등을 class로 작성한다.

  6. 컴파일러가 모든 Processor가 실행되었는지 확인하고 다음 Round를 진행하거나 실행 종료한다.

    3~6을 반복하게 되며, 각 Round 마다 처리할 각각의 Annotation을 식별한다.

 

Annotation Processor 구현

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface SampleAnnotation {

        String name() default "";

}

//------

@SupportedAnnotationTypes("com.example.annotation.SampleAnnotation")
@AutoService(Processor.class)
public class SampleProcessor extends AbstractProcessor {

        @Override
        public SourceVersion getSupportedSourceVersion() {
                return SourceVersion.latestSupported();
        }

        @Override
    public boolean process(Set<? extends TypeElement> annotations, 
      RoundEnvironment roundEnv) {

                for (TypeElement annotation : anotations) {
                        for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
                                processingEnv.getMessager().printMessage(Diagnostic.kind.NOTE, "found SampleAnnotation : " + element);
                        }
                }

                return true;
    }

}

 

 

 

참고 자료

'Live Study' 카테고리의 다른 글

Live Study_Week 15. Lambda Expression  (0) 2021.03.01
Live Study_Week 13. I/O  (0) 2021.02.20
Live Study_Week 11. Enum  (0) 2021.01.28
Live Study_Week 09. 예외 처리  (0) 2021.01.11
Live Study_Week 08. 인터페이스  (0) 2021.01.05

+ Recent posts