Home

Published

- 6 min read

[ JAVA ] 어노테이션(Annotation)이란?

img of [ JAVA ] 어노테이션(Annotation)이란?

프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 바로 어노테이션이다. 어노테이션은 주석(comment)처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점이 있다.

어노테이션의 동작 원리

image

결론부터 말하자면 어노테이션은 컴파일과정에서 수행된다.(런타임이 아니다.)

모든 자바 소스파일들은 parser에 들어간다. parser는 Abstract Syntax Trees를 생성하고, 컴파일러의 symbol table을 채운다. 그 다음, 각 어노테이션에 대해 해당하는 Annotation Processor가 호출되며, 이는 새로운 소스 파일들을 생성할 수 있다.(어노테이션에 해당하는 부분이 코드로 바뀌어 새로운 소스파일을 생성한다.)

새로 생성된 모든 소스 파일들은 다시 parser로 피드백되어 parsing되어야 하며 추가적인 어노테이션을 포함할 수 있다. 마지막으로, 새로운 소스 파일이 더 이상 생성되지 않으면, syntax tree들이 클래스 파일로 변환된다.(.class) 이 마지막 단계에는 외부 라이브러리에 대한 참조를 해결하는 과정이 포함되며, 이 라이브러리의 클래스들도 컴파일되어야 한다. 그러나 이들은 어노테이션 처리 대상이 되지 않는다.

주목해야 할 중요한 점은 어노테이션 프로세서는 새로운 소스 파일만을 생성할 수 있으며 기존 파일을 수정할 수 없다는 것이다. 또한 javac가 컴파일 중에 자체 JVM 내에서 어노테이션 프로세서를 실행한다는 것을 아는 것도 중요하다. 이는 소스 파일을 생성하기 위해 임의의 Java 라이브러리를 사용할 수 있으며 테스트도 작성할 수 있다는 것을 의미한다.

일부 어노테이션은 런타임에도 사용 가능하도록 설계되었다.(@Retention(RetentionPolicy.RUNTIME)) 이런 어노테이션은 컴파일 후에도 클래스 파일에 정보가 남아있어, 런타임에 Reflection으로 접근할 수 있다.

class.getAnnotations()와 컴파일타임 어노테이션

위에서 말하는 getAnnotations()는 런타임 어노테이션에 해당하는 어노테이션들을 불러온다. 그래서 컴파일 타임의 어노테이션들은 불러오지 않는다. 예시를 보자.

   
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SuppressWarnings({})
public class HelloController {

  @GetMapping("/hello")
  public String hello(@RequestParam(defaultValue = "") String name) {
    return "Hello " + name;
  }
}

이렇게 간단한 컨트롤러 코드를 작성하였다. 이 클래스에 사용한 어노테이션은 총 두개, @RestController, @SuppressWarnings 이다. 이중에서 @RestController는 런타임시 적용되는 어노테이션이고, @SuppressWarnings는 컴파일타임시 적용되는 어노테이션이다.

둘의 정보를 모두 볼 수 있게 코드를 작성하고 결과를 보자.

   Class<?> clazz = HelloController.class;

System.out.println(Arrays.toString(clazz.getAnnotations()));
  • 결과
image

보다시피 RestController 하나만 출력되는 것을 볼 수 있다.

표준 어노테이션(Standard Annotations)

image

자바에서 기본적으로 제공하는 애너테이션들은 몇 개 없다. 그나마 이들의 일부는 ‘메타 어노테이션(meta annotation)‘으로 어노테이션을 정의하는데 사용되는 어노테이션의 어노테이션이다.

image

*자바에서 기본적으로 제공하는 표준 어노테이션(이 붙은 것은 메타 어노테이션)

메타 어노테이션(meta anotation)

앞에서 설명했듯이, 어노테이션을 위한 어노테이션이다. 실제 @Controller 어노테이션 코드를 살펴보자.

   package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}

Controller 어노테이션을 보면 다른 어노테이션들이 있는 것을 볼 수 있다. 메타 어노테이션은 어노테이션을 정의할 때, 어노테이션의 적용대상(Target)이나 유지기간(Retention) 등을 지정하는 데 사용된다.

메타 어노테이션은 ‘java.lang.annotation’ 패키지에 포함되어 있다.

나머지 상세한 어노테이션들에 대한 설명은 위 표에 하이퍼링크를 달거나, 따로 정리해두려고 한다.

출처: