[Spring]Custom Annotation(커스텀 애노테이션)

2020년 09월 30일 by Xion

    [Spring]Custom Annotation(커스텀 애노테이션) 목차

 

| Custom Annotation(커스텀 애노테이션)이란?


  • 메타 애노테이션
  • 조합 애노테이션

 

 

커스텀 애노테이션 선언 

public @interface userAnnotation{}  // 커스텀 애노테이션 선언

- @interface와 함께 사용할 이름을 적어주면 커스텀 애노테이션이 완성됩니다.

- 이 애노테이션을 클래스,필드,메서드 같은 곳에 붙이션 애노테이션으로써 껍데기 같은 역할은 할 수 있습니다.

 

//커스텀 애노테이션 사용 예
@userAnnotation
public class explain{

	public static void main(String[] args){
    System.out.println("Hello World");
    }
    
 }

 

하지만,

(커스텀 애노테이션 로직이 작성 되어있다는 가정 하) 위와 같이 선언 후 코드를 돌려보면 아무런 동작도 하지 않습니다.

이유는 어노테이션을 주석과 같은 취급을 받기 때문에 정보가 클래스까지는 남아있지만 바이트 코드를 로딩하고 난 후 메모리에는 어노테이션의 정보는 가지고 오지 않기 때문입니다.

 

메모리에도 적재하기 위해서는 어노테이션 class에 "@Retention" ,"@Target"이라는 메타 어노테이션을 붙여줘야만 합니다.

 

| @Retention 이란?

"해당 애노테이션 정보를 언제까지 유지할 것인가"에 관한 정보를 알려주는 애노테이션입니다.

 

커스텀 애노테이션을 작성한 곳에 해당 애노테이션 정보를 언제까지 유지할지 @Retention 애노테이션을 명시해줍니다.

@Retetion 속성

  • Source : 소스 코드까지만 유지. 즉, 컴파일 하면 해당 애노테이션 정보는 사라진다는 이야기.
  • Class : 컴파일 한 .class 파일에도 유지. 즉, 런타임 시, 클래스를 메모리로 읽어오면 해당 정보는 사라진다.
  • Runtime : 클래스를 메모리에 읽어왔을 때까지 유지 ! 코드에서 이 정보를 바탕으로 특정 로직을 실행할 수 있다.
@Retention(RetentionPolicy.RUNTIME)    //@interface로 작성된 커스텀 애노테이션에 적어줘야합니다.
public @interface userAnnotation {
}

 

| @Target이란?

 

"해당 애노테이션을 어느 시점에 적용할것인가"에 대한 애노테이션입니다.

위의 예에서는 모든 곳에 사용할 수 있게 된다. 즉, 필드, 메소드, 클래스 등 모든 곳에 어노테이션을 붙일 수 있게 되는데 어노테이션 사용을 허가하는 target을 설정할 수 있다.

 

@Target 속성

 

  • TYPE : class, interface, enum에 적용된다. 

  • FIELD : 클래스 필드 변수

  • METHOD : 메서드

  • PARAMETER : 메서드 인자

  • CONSTRUCTOR : 생성자

  • LOCAL_VARIABLE : 로컬 변수

  • ANNOTATION_TYPE : 어노테이션 타입에만 적용된다

  • PACKAGE : 패키지 

  • TYPE_PARAMETER : 자바8부터 추가된 값으로 제네릭 타입 변수에 적용된다. (ex. MyClass<T>)

  • TYPE_USE : 자바8부터 추가된 값으로 어떤 타입에도 적용된다 (ex. extends, implements, 객체 생성시등등)

 

 

  • MODULE : 자바9부터 추가된 값으로 모듈에 적용된다

 

 

@Retention(RetentionPolicy.RUNTIME)    //@interface로 작성된 커스텀 애노테이션에 적어줘야합니다.
@Target({ELement.TYPE,ElementType.FIELD}) //사용할 위치 (타입,필드)
public @interface userAnnotation {
}
@userAnnotation
public class Book {
    private static String B = "BOOK";

    @userAnnotation
    private static final String C = "BOOK";


    @userAnnotation // '@userAnnotation' not applicable to constructor 컴파일에러
    // -> userAnnotation에서 "Type" 과 "FIELD"로만 적용했기 때문
    public Book(){

    }
    
    //'@userAnnotation' not applicable to parameter 컴파일에러.
    public Book(@userAnnotation String a, String d, String e) {
        this.a = a;
        this.d = d;
        this.e = e;
    }

    @userAnnotation
    private void f(){
        System.out.println("F");
    }

    public void g(){
        System.out.println("g");
    }

    public int h(){
        return 100;
    }

}

- userAnnotation에서 속성으로 TYPE과 FILED로만 적용을 시켰기 때문에(나머지에서) 컴파일 에러가 납니다.

 

그 외) 어노테이션

 

  • @Inherited

    • 이 어노테이션을 선언하면 자식클래스가 어노테이션을 상속 받는다

  • @Documented

    • 이 어노테이션을 선언하면 새로 생성한 어노테이션이 자바 문서 생성시 자바 문서에도 포함시키는 어노테이션이다. 

  • @Repeatable

    • 자바8에 추가된 어노테이션으로 반복 선언을 할 수 있게 해준다.

 

 

이런식으로 커스텀 애노테이션을 적용하여 AOP가 적용될 위치나 특정 상황에 맞게 사용하면 유용할 것 같습니다 !