// 사용 - 같은 어노테이션 여러 번@Schedule(day = "MON")@Schedule(day = "WED")@Schedule(day = "FRI")publicvoiddoTask() { }
Java 8 이전엔 이게 안 돼서 배열로 직접 감싸야 했습니다.
자바 기본 제공 Annotation
자바에서는 일부 Annotation 기능을 제공합니다.
컴파일러용 어노테이션
@Override// 부모 메서드 재정의 확인 (오타 시 컴파일 에러)@Deprecated// 더 이상 사용하지 않음 (사용 시 경고)@SuppressWarnings// 특정 경고 무시@FunctionalInterface// 함수형 인터페이스임을 명시 (추상 메서드 1개 강제)@SafeVarargs// 가변인자 제네릭 경고 억제
@Overridepublicbooleanequals(Object obj) { ... }
@DeprecatedpublicvoidlegacyMethod() { ... }
@SuppressWarnings("unchecked")
List<String> list = (List<String>) rawList;
@FunctionalInterfaceinterfaceCalculator {
intcalc(int a, int b); // 추상 메서드 정확히 1개
}
@SuppressWarnings 주요 값
@SuppressWarnings("unchecked")// 제네릭 타입 캐스팅 경고@SuppressWarnings("deprecation")// deprecated 사용 경고@SuppressWarnings("rawtypes")// raw 타입 사용 경고@SuppressWarnings({"unchecked", "deprecation"})// 여러 개
Spring Annotation
📝Note
해당 파트는, Spring Framework 의 Annotation 으로, 순수 JAVA 에서 제공되거나 활용되는 기능은 아닙니다.
Spring boot 프레임워크에서는, 유용하게 사용할 수 있는 합성 어노테이션을 제공합니다.
이 기능은, 어노테이션 위에 다른 어노테이션을 붙여서 여러 어노테이션을 하나로 합칠 수 있는 기능입니다.
대표적인 예시로 @RestController 가 있습니다.
@RestController는 사실 단독 기능이 아닌, @Controller + @ResponseBody를 합친 기능입니다.
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Controller// ← 메타 어노테이션으로 @Controller 를 붙임@ResponseBody// ← @ResponseBody 도 붙임public@interface RestController {
@AliasFor(annotation = Controller.class)
String value()default"";
}
그래서 아래 둘은 사실상 동일하게 동작합니다.
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Controller// ← 메타 어노테이션으로 @Controller 를 붙임@ResponseBody// ← @ResponseBody 도 붙임public@interface RestController {
@AliasFor(annotation = Controller.class)
String value()default"";
}
해당 기능은 자바의 표준 기능이 아닌 스프링의 기능입니다.
자바 표준 리플렉션은 이 메타 어노테이션을 직접 인식하지는 못합니다.
// 표준 리플렉션
UserController.class.isAnnotationPresent(Controller.class);
// → false! (@RestController 만 직접 달려있다고 봄)
@AliasFor는 합성 어노테이션에서 바깥 어노테이션의 요소 값을 안쪽 어노테이션으로 넘겨주는 Spring의 어노테이션입니다.
@Controllerpublic@interface RestController {
@AliasFor(annotation = Controller.class)// 이 value를 Controller의 value로 전달
String value()default"";
}
@AliasFor가 없으면 함성만 되고, 값 전달은 전혀 되지 않습니다.
ℹ️Info
해당 기능은 Spring Framework 4.2 부터 지원된 기능으로 Boot 기준으로는 1.3 이상입니다.
Boot 를 쓰는 대부분의 개발자는 사용 가능합니다.
정리
사실 이렇게 정의를 하더라도 실제로 무언가 어플리케이션에서 동작이 변경되거나 기능이 추가되는 것은 아닙니다.
Annotation 은 단순히 메타 데이터를 주입만 하는 기능이고, Spring 의 AOP, Java의 리플렉션 등의 기능으로 "어떤 동작"을 할 지 처리해줘야 합니다.