어노테이션이란 자바와 같은 몇몇 프로그래밍 언어에서 제공하는 메타데이터(metadata)의 한 형태
인데요. 클래스나 인터페이스를 컴파일 및 실행할 때 처리 방법을 알려주는 설정 정보를 의미하며, HTML의 메타데이터와 유사한 역할을 수행
합니다.
이러한 어노테이션은 자바 내장 라이브러리에 존재하는 @Override
, , @Deprecated
@SuppressWarnings
, SafeVarargs
, FunctionalInterface
등이 존재하며, 그 중 @Override
가 가장 많이 사용되는 어노테이션입니다.
우선 어노테이션을 적용하기 전에, 적용할 대상과 유지 범위를 지정할 수 있는데요. 이는 @Target
와 RetentionPolicy
어노테이션으로 지정하며, 적용 대상의 범위는 ElementType의 열거 상수
가 됩니다.
참고로 ElementType 열거 상수
란 ElementType의 종류를 모아 놓은 내장 열거형(enum) 중 하나
로서 목록은 다음과 같습니다.
public enum ElementType { TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE }
그리고 이러한 어노테이션의 적용 대상을 설정하는 방법은 다음과 같습니다.
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) // 해당 어노테이션은 클래스, 인터페이스, 필드, 메서드에 어노테이션을 설정하겠다는 뜻. public @interface TempAnnotation{ }
마지막으로 어노테이션의 유지 범위는 RetentionPolicy 열거 상수의 속성들 중에서 지정
하면 되며, RetentionPolicy 열거 상수
는 다음과 같습니다.
public enum RetentionPolicy { SOURCE(컴파일 동안 적용), CLASS(메모리에 적재되는 동안 적용), RUNTIME(런타임 동안 적용) }
이러한 RetentionPolicy의 사용법은 다음과 같습니다.
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) // 런타임, 즉 실행이 되는 동안 해당 어노테이션을 유지 public @interface TempAnnotation{ }
우선 어노테이션을 만들기 위해서는 기본적으로 인터페이스를 사용하며, 인터페이스에는 사용자가 속성과 기본값을 지정할 수 있습니다.
public @interface TempAnnotation{ String value() default "Re_Go"; // 기본값을 Re_Go로 설정하는데, value 속성은 지정된 어노테이션의 기본 속성이기 때문에 추후에 단독으로 값을 할당할 때 따로 변수명을 지정하지 않아도 됩니다. int age(); boolean marrieage(); }
이렇게 설정한 어노테이션을 사용하기 위해서는 해당 어노테이션에 있는 속성마다 값을 할당해주면 되는데요.
@TempAnnotation(value = "Reall Re_Go", age = 30, marrieage = false); // "Reall Re_Go"는 value에 할당 되는 값으로서 value속성이 해당 어노테이션의 기본 속성이기 때문에 추후에 값을 설정할 때 value 속성만 단독으로 지정할 경우 value를 명시하지 않아도 되나, 다른 속성들과 함께 값을 할당할 경우 value를 명시해 주어야 합니다.
위에서 설정된 어노테이션을 적용하기 위해서는 적용 대상 Target에 해당하는 타입을 만들어 정의를 해줘야 합니다.
package default; public class AnnotationClass { @TempAnnotation(value = "Reall Re_Go", age = 30, marriage = false) public void defaultMethod() { System.out.println("어노테이션 정보") } }
그리고 이렇게 적용 된 클래스의 정보(어노테이션)를 호출하기 위해서는 리플렉션 작업
을 해줘야 하는데요. 이를 위해선 reflect
패키지를 임포트 해주어야 하며, 쉽게 얘기해서 어노테이션의 정보를 불러와주는 API
라고 생각하시면 됩니다.
사용법은 Class ,Method, Constructor 키워드로 불러오고 싶은 대상의 타입을 지정한 후 정보들을 불러와 담은 후, 어노테이션이 지정된 각 변수를 어노테이션 클래스의 변수에 할당 후 출력하면 됩니다.
package default; import java.lang.reflect.*; public class Main { public static void main(String[] args) throws NoSuchMethodException { try { // 1. AnnotationClass 파일의 클래스 정보 가져오기 Class<AnnotationClass> mainClass = AnnotationClass.class; // 2. 가져온 클래스 정보의 defaultMethod 메서드 가져오기 Method method = mainClass.getMethod("defaultMethod"); // 3. 어노테이션 가져오기 (해당 메서드에 어노테이션의 클래스 정보가 존재한다면 메서드의 어노테이션 정보를 가져와 속성들을 각각 출력) if (method.isAnnotationPresent(TempAnnotation.class)) // 만약 가져온 메서드에 TempAnnotation의 클래스(인터페이스 생성시 자동으로 클래스도 생성되며, 인터페이스의 정보를 담고 있습니다.)가 해당 메서드에 존재할 경우 다음 작업을 수행합니다.{ TempAnnotation annotation = method.getAnnotation(TempAnnotation.class); // 메서드의 어노테이션 정보를 가져와 TempAnnotation 클래스 (어노테이션에서 설정한 클래스 정보)의 변수에 할당 System.out.println("Value: " + annotation.value()); System.out.println("Age: " + annotation.age()); System.out.println("Marriage: " + annotation.marriage()); } else { System.out.println("TempAnnotation not found on defaultMethod"); } } catch (NoSuchMethodException e) { System.out.println("Method not found: " + e.getMessage()); } } }
★ 다만 앞서 살펴본 자바에서의 기본적인 어노테이션은 거의 @Override가 사용되고, 그마저도 자동적으로 주입되는 경우도 적잖으며,
후에 스프링을 들어가게 되면 의존성 주입 개념으로 다른 라이브러리들의 어노테이션을 사용하기 때문에 어노테이션의 쓰임새는 스프링에서부터 그 진가를 발휘하게 된답니다.