Meta Annotation

package hello.core.scan.filter;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
package hello.core.scan.filter;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}

김영한님 스프링 강의 복습 중, 위 어노테이션을 사용법이 궁금해서 찾아봤다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented

위 어노테이션은 @Component에서 끌어다 썼는데, 무슨의미일까?

meta-annotaiton

meta-annotation은 다른 annotation에서도 사용되는 annotation 의 경우를 말하며 custom-annotation 을 생성할 때 사용된다.

@Target

@Target 은 Java compiler 가 annotation 이 어디에 적용될지 결정하기 위해 사용한다.

예를 들어 위에서 사용한 @Service 의 ElementType.TYPE 은 “해당 Annotation 은 타입 선언 시 사용한다는 의미”이다.

종류는 다음과 같다.


ElementType.PACKAGE : 패키지 선언
ElementType.TYPE : 타입 선언
ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
ElementType.CONSTRUCTOR : 생성자 선언
ElementType.FIELD : 멤버 변수 선언
ElementType.LOCAL_VARIABLE : 지역 변수 선언
ElementType.METHOD : 메서드 선언
ElementType.PARAMETER : 전달인자 선언
ElementType.TYPE_PARAMETER : 전달인자 타입 선언
ElementType.TYPE_USE : 타입 선언


@Retention

@RetetionAnnotation이 실제로 적용되고 유지되는 범위를 의미한다.

Policy 에 관련된 Annotation으로 위의 예시에선 컴파일 이후에도 JVM 에서 참조가 가능한 RUNTIME으로 지정했다.

종류는 다음과 같다.


RetentionPolicy.RUNTIME
RetentionPolicy.CLASS
RetentionPolicy.SOURCE


  • RetentionPolicy.RUNTIME 은 컴파일 이후에도 JVM 에 의해서 계속 참조가 가능하다. 주로 리플렉션이나 로깅에 많이 사용된다.

  • RetentionPolicy.CLASS 은 컴파일러가 클래스를 참조할 때가지 유효하다.

  • RetentionPolicy.SOURCE 은 컴파일 전까지만 유효하다. 즉, 컴파일 이후에는 사라지게 된다.

@Documented

@Documented은 Java 어노테이션(annotation) 중 하나로, 이 어노테이션을 사용하면 해당 어노테이션이 적용된 코드 요소의 문서화에 도움이 된다.
즉, 해당 어노테이션이 붙은 요소에 대한 문서가 자동으로 생성되고 javadoc과 같은 도구를 사용하여 추출된다.