티스토리 뷰

JAVA

[JAVA] Annotation 알아보기

DevBee 2022. 2. 19. 14:21

Annotation이란?

어노테이션은 사전적 의미로는 주석이라는 뜻입니다. 자바에서 사용될 때의 어노테이션은 코드 사이에 주석처럼 쓰여서 특별한 의미, 기능을 수행하도록 하는 기술을 말합니다. 즉, 프로그램에게 추가적인 정보를 제공해주는 메타데이터(meta data: 데이터를 위한 데이터)라고 볼 수 있습니다.

 

Annotation을 사용하는 용도

Annotation을 사용하는 용도는 아래와 같이 크게 3가지가 있습니다.

 

  • 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공
  • 소프트웨어 개발툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보 제공
  • 실행시(런타임시)특정 기능을 실행하도록 정보를 제공

 

Spring에서 제공되는 대부분의 Annotation은 런타임 시 특정 기능을 실행하도록 정보를 제공하는 용도로 사용되고 있습니다.

 

Annotation 사용 방법

기본적으로 Annotation을 사용하는 순서는 다음과 같습니다.

 

  1. 어노테이션 정의
  2. Target에 어노테이션 배치
  3. 코드가 실행되는 중에 Reflection을 이용하여 추가 정보를 획득해 기능 실시

1. 어노테이션 정의

어노테이션을 적용할 때는 어노테이션이 어디에 적용되며 언제까지 어노테이션 소스가 유지될 것인지를 설정하여야 합니다.

@Target({ElementType.[적용대상]})
@Retention(RetentionPolicy.[정보유지되는 대상])
public @interface [어노테이션명]{
	public 타입 elementName() [default 값]
    ...
}

 

@Target에는 어떠한 값(ex : 클래스, 필드, 메서드 ...)에 어노테이션을 적용할 것이지 나타낼 수 있는데 넣을 수 있는 값은 다음 표와 같습니다.

 

EnumType 열거 상수 적용 대상
TYPE 클래스, 인터페이스, 열거 타입
ANNOTATION_TYPE 어노테이션
FIELD 필드
CONSTRUCTOR 생성자
METHOD 메소드
LOCAL_VARIABLE 로컬 변수
PACKAGE 패키지

 

@Retention에는 어노테이션 값들을 언제까지 유지할 것인지 값을 입력하는데 각 값이 가지는 의미는 다음 표와 같습니다. 보통 어노테이션은 Runtime시에 많이 사용하므로 대부분의 어노테이션의 Retention 값은 RUNTIME으로 되어있습니다.

 

RetentionPolicy 열거 상수 설명
SOURCE 소스 상에서만 어노테이션 정보를 유지합니다. 소스 코드를 분석할 때만 의미가 있으며, 바이트 코드 파일에는 정보가 남지 않습니다.
CLASS 바이트 코드 파일까지 어노테이션 정보를 유지합니다. 하지만 리플렉션을 이용해서 어노테이션 정보를 얻을 수는 없습니다.
RUNTIME 바이트 코드 파일까지 어노테이션 정보를 유지하면서 리플렉션을 이용해서 런타임에 어노테이션 정보를 얻을 수 있습니다.

 

2. Target에 어노테이션 배치

 

3. 코드가 실행되는 중에 Reflection을 이용하여 추가 정보를 획득해 기능 실시

 

아래 예제를 통해 어노테이션의 배치와 사용에 대해 알아보겠습니다.

 

예제

작성하려는 예제 소스는 다음과 같습니다.

 

  • MyAnnotation.java (어노테이션)
  • MyService.java (사용되는 클래스)
  • MyMain.java (MyService를 사용하는 클래스)

 

다음 코드는 MyMain 클래스가 MyService 클래스의 메서드에서 MyAnnotation 어노테이션 설정이 있는지 확인하고 각 메서드에 설정된 어노테이션에 삽입된 값에 따라 특정값을 일정한 숫자만큼 출력하는 예제입니다.

 

[MyAnnotation.java]

package myannotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	String value() default "-";
	int number() default 15;
	
}

 

[MyService.java]

package myannotation;

public class MyService {
    @MyAnnotation
    public void method1() {
        System.out.println("========== @MyAnnotation ===========");
    }

    @MyAnnotation("*")
    public void method2() {
        System.out.println("========== @MyAnnotation(\"*\") ===========");
    }

    @MyAnnotation(value = "*", number = 10)
    public void method3() {
        System.out.println("========== @MyAnnotation(value = \"*\", number = 10) ===========");
    }
}

 

[MyMain.java]

package myannotation;

import java.lang.reflect.Method;

public class MyMain {
    public static void main(String[] args) {
        Method[] methodList = MyService.class.getMethods();
		
        for(Method m : methodList) {
            if(m.isAnnotationPresent(MyAnnotation.class)) {
                System.out.println(m.getName());
                MyAnnotation annotation=m.getDeclaredAnnotation(MyAnnotation.class);
				
                String value=annotation.value();
                int number=annotation.number();
                for(int i=0;i<number;i++) {
                    System.out.print(value);
                }
                System.out.println();				
            }
        }
    }
}

 

[결과값]

 

 

어노테이션 정보를 얻기 위한 메소드를 살펴보면 다음과 같습니다.

 

리턴 타입 메소드명(매개변수)
boolean isAnnotationPresent(Class<? Extends Annotation> annotationClass)
지정한 어노테이션이 적용되었는지 여부. Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 true를 리턴합니다.
Annotation getAnnotation(Class<T> annotationClass)
지정한 어노테이션이 적용되어 있으면 어노테이션을 리턴하고 그렇지 않다면 null을 리턴. Class에서 호출했을 경우 상위 클래스에 적용된 경우에도 어노테이션을 리턴합니다.
Annotation[] getAnnotations()
적용된 모든 어노테이션을 리턴. Class에서 호출했을 경우 상위 클래스에 적용된 어노테이션도 모두 포함합니다. 적용된 어노테이션이 없을 경우 길이가 0인 배열을 리턴합니다.
Annotation[] getDeclaredAnnotations()
직접 적용된 모든 어노테이션을 리턴. Class에서 호출했을 경우 상위 클래스에 적용된 어노테이션은 포함되지 않습니다.

 

참고

 

 

'JAVA' 카테고리의 다른 글

[Collection] 일급 컬렉션  (0) 2023.02.09
[List] List.of()로 List 생성 시 주의! (feat. 불변 컬렉션)  (0) 2023.01.24
[Java Version] Java 8 vs 11vs 17  (0) 2022.02.11
[Java] stream 알아보기  (0) 2022.02.11
[Java Study 15] 람다식  (0) 2021.05.15
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함