@interface 키워드를 사용Retention과 Target을 선언한다.✏️ 어노테이션은 주로 프로그래밍 언어에서 특정 기능이나 동작을 정의하거나 설명하는데 사용되는 메타데이터를 의미한다.
meta-annotaiton)annation 에서도 사용되는 annotation 의 경우를 말하며 custom-annotation 을 생성할 때 주로 사용된다.@Target@Target(ElementType.FIELD)
Java compiler 가 annotation이 어디에 적용될지 결정하기 위해 사용한다.ElementType의 값들을 사용하여 지정할 수 있다.ElementType.PACKAGE : 패키지 선언
ElementType.TYPE : 타입 선언
ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
ElementType.CONSTRUCTOR : 생성자 선언
ElementType.FIELD : 멤버 변수 선언
ElementType.LOCAL_VARIABLE : 지역 변수 선언
ElementType.METHOD : 메서드 선언
ElementType.PARAMETER : 전달인자 선언
ElementType.TYPE_PARAMETER : 전달인자 타입 선언
ElementType.TYPE_USE : 타입 선언
@Retention@Retention(RetentionPolicy.RUNTIME)
Annotation 이 실제로 적용되고 유지되는 범위를 의미한다.RetentionPolicy.RUNTIME : 컴파일 이후에도 JVM 에 의해서 계속 참조가 가능하다. (주로 리플렉션이나 로깅에 많이 사용됨)
RetentionPolicy.CLASS : 컴파일러가 클래스를 참조할 때가지 유효하다.
RetentionPolicy.SOURCE : 컴파일 전까지만 유효하다. (컴파일 이후에는 사라짐)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface NotEmpty {
String message() default "Field cannot be empty";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Range {
int min() default 0;
int max() default Integer.MAX_VALUE;
String message() default "Value must be within range";
}
class User {
@NotEmpty(message = "사용자명은 필수입니다")
private String username;
@Range(min = 0, max = 150, message = "나이는 0-150 사이여야 합니다")
private int age;
}
class AnnotationProcessor {
public static void validateFields(Object obj) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
// @NotEmpty 검증
if (field.isAnnotationPresent(NotEmpty.class)) {
try {
Object value = field.get(obj);
if (value == null || value.toString().trim().isEmpty()) {
NotEmpty annotation = field.getAnnotation(NotEmpty.class);
throw new IllegalArgumentException(annotation.message());
}
} catch (IllegalAccessException e) {
// 예외처리
}
}
// @Range 검증
if (field.isAnnotationPresent(Range.class)) {
try {
Object value = field.get(obj);
if (value instanceof Integer) {
int intValue = (Integer) value;
Range annotation = field.getAnnotation(Range.class);
if (intValue < annotation.min() || intValue > annotation.max()) {
throw new IllegalArgumentException(annotation.message());
}
}
} catch (IllegalAccessException e) {
// 예외처리
}
}
}
}
출처
Spring Boot 기초: 어노테이션 활용하기 (1편)
Spring Boot 심화: 커스텀 어노테이션 만들기 (2편)
[Spring] Meta Annotation 이란?(@Target, @Retention)
Java annotation(2) - Custom Annotation