Custom Annotation 생성하기 @interface 알짜만 빼먹기
@Annotation을 생성하는 방법에 대해 알아보겠습니다.
1. annotation의 생성
annotation은 @interface로 생성할 수 있습니다.
public @interface CustomAnotation{};
이렇게 생성한 어노테이션은 어디에든 붙여서 사용할 수 있습니다.
@CustomAnnotation
@RequiredArgsConstructor
public class TestController {
@CustomAnnotation
private final TestService service;
@CustomAnnotation
@GetMapping(value="hello")
public String getPage(){
return "hello"
}
}
2. Meta Annotation의 종류
하지만 여기에 Meta Annotation을 추가하면 구성할 시점, 위치를 제한할 수 있습니다.
@Target(ElementType.[적용할 대상])
@Retention(RetentionPolicy.[정보유지 대상]
public @interface CustomAnotation{};
2.1 ElementType의 종류
ANNOTATION_TYPE - Annotation 유형에 선언
CONSTRUCTOR - 생성자에 선언
FIELD - 필드에 선언
LOCAL_VARIABLE - 지역 변수에 선언
METHOD - 메소드에 선언
PACKAGE - 패키지에 선언
PARAMETER - 매개변수에 선언
TYPE - 클래스, 인터페이스 또는 enum에 선언
TYPE_PARAMETER - 유형 매개변수에 선언
TYPE_USE - 유형의 사용
예를들어 @Target(ElementType.METHOD) 를 추가할 경우 메소드 이외에 추가된 어노테이션은 에러를 발생시킵니다.
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface CustomAnnotation {}
@CustomAnnotation --> 'The annotation @CustomAnnotation is disallowed for this location'
@RequiredArgsConstructor
public class TestController {
@CustomAnnotation --> 'The annotation @CustomAnnotation is disallowed for this location'
private final TestService service;
@CustomAnnotation
@GetMapping(value="hello")
public String getPage(){
return "hello"
}
}
여러개 사용 가능
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
public @interface CustomAnnotation {}
link: https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/ElementType.html#METHOD
2.2 RetentionPolicy 의 종류
SOURCE - 컴파일 시점에 참조될 때 (.java)
CLASS - 컴파일러에 의해 클래스에 등록되지만, 런타임 시 VM에 의해 참조될 필요 없을 때, 기본 동작 (.class)
RUNTIME - 컴파일러에 의해 클래스에 등록고 런타임시에 VM에 의해 참조 될 때 (언제나)
Link : https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html
여러개 사용 불가
2.3 기타 Custom Annotation
Documented
해당 어노테이션을 Javadoc에 포함시켜줌
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
Inherited
해당 어노테이션을 상속할 수 있게 함
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
Repeatable
연속적으로 어노테이션을 선언할 수 있게 함
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
/**
* Indicates the <em>containing annotation type</em> for the
* repeatable annotation type.
* @return the containing annotation type
*/
Class<? extends Annotation> value();
}
Indexed
빈 어노테이션, 단순히 메타 어노테이션을 붙여주는 역할을 함
ex) Indexted annotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Indexed {
}
3. 변수 전달
변수는 아래와 같이 전달이 가능하고 타입은 기본형, String, enum, 어노테이션, Class 만 허용됩니다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
String name();
String value();
}
@RequiredArgsConstructor
public class TestController {
private final TestService service;
@CustomAnnotation(name="이름", value="값")
@GetMapping(value="hello")
public String getPage(){
return "hello"
}
}
3.1 default 값 설정
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
String name() default "geonlee";
String value() default "hi";
}
4. 응용
Custom Mapper Annotation을 활용한 DB 구분은 아래의 Link를 참고하세요.
Link : https://aljjabaegi.tistory.com/440
5. GetMapping 들여다보기
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
/**
* Alias for {@link RequestMapping#name}.
*/
@AliasFor(annotation = RequestMapping.class)
String name() default "";
/**
* Alias for {@link RequestMapping#value}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
/**
* Alias for {@link RequestMapping#path}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
/**
* Alias for {@link RequestMapping#params}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
/**
* Alias for {@link RequestMapping#headers}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
/**
* Alias for {@link RequestMapping#consumes}.
* @since 4.3.5
*/
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
/**
* Alias for {@link RequestMapping#produces}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
}
이제 위 코드를 보시면 이해가 되실꺼에요.
Method에만 추가 할 수 있고, 런타임에 실행되며, Javadoc 에 포함시키고, Get Method 일때 동작하는 어노테이션이다.
변수로는 name, value, path, params...등등이 있다. name을 제외한 모든 변수는 복수설정이 가능하다.
여기에 추가로 @AliasFor 가 나오는데 이 어노테이션은 별칭을 설정할 수 있습니다. name, value, annotaion을 받을 수 있으며, GetMapping의 변수들은 RequestMapping annotation의 변수들을 가리키게 됩니다.