Programing/JAVA

Custom Annotation 생성하기 @interface 알짜만 빼먹기

리커니 2022. 11. 15. 17:51
반응형

@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

 

ElementType (Java Platform SE 8 )

The constants of this enumerated type provide a simple classification of the syntactic locations where annotations may appear in a Java program. These constants are used in java.lang.annotation.Target meta-annotations to specify where it is legal to write

docs.oracle.com

 

2.2 RetentionPolicy 의 종류

SOURCE - 컴파일 시점에 참조될 때 (.java)

CLASS - 컴파일러에 의해 클래스에 등록되지만, 런타임 시 VM에 의해 참조될 필요 없을 때, 기본 동작 (.class)

RUNTIME - 컴파일러에 의해 클래스에 등록고 런타임시에 VM에 의해 참조 될 때 (언제나)

 

Link : https://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html

 

RetentionPolicy (Java Platform SE 7 )

 

docs.oracle.com

여러개 사용 불가

 

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

 

Spring Mybatis 멀티 database 연동 다중, 복수 데이터베이스 연동 oracle, mysql

Spring Mybatis 멀티 database 연동 다중, 복수 데이터베이스 연동 oracle, mysql Spring Mybatis의 Mapper interface를 사용하는 환경에서 복수의 database 설정을 하는 방법을 알아보겠습니다. ibatis 환경에서 복수의

aljjabaegi.tistory.com

 

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의 변수들을 가리키게 됩니다.

 

 

반응형