아래의 내용은 java_grammer 레파지토리 C10Annotation 디렉터리에 저장되어있는 내용을 정리함
리플렉션 기본 이해 → 어노테이션 정의 → 실전 검증 적용 순서로 진행된다. 스프링의 @Autowired, @Valid 같은 기술의 근간 기술이다.
1. 클래스 정보 런타임 조회 (이름, 메서드, 필드)
2. 메서드 동적 호출
3. private 필드 접근/수정
4. 객체 동적 생성
Person p1 = new Person(); // {name='null', age=0}
Field nameField = Person.class.getDeclaredField("name");
nameField.setAccessible(true); // private 접근 허용
nameField.set(p1, "jiyean"); // 값 직접 설정
setAccessible(true): 보안 제약 무시하고 private 필드 접근 가능하게 하는 핵심 메서드이다.
@Retention(RetentionPolicy.RUNTIME) // 런타임에 리플렉션 접근 가능
@interface NotEmpty {
String message() default "필수 입력사항입니다";
}
class Member {
private String name;
@NotEmpty(message = "이메일은 필수입니다") // 선언적 검증 규칙
private String email;
}
static void validate(Object object) {
for (Field f : object.getClass().getDeclaredFields()) {
if (f.isAnnotationPresent(NotEmpty.class)) { // 어노테이션 존재 확인
// 검증 로직 실행
}
}
}
f.setAccessible(true);
String value = (String) f.get(object);
if (value == null || value.isEmpty()) {
NotEmpty ne = f.getAnnotation(NotEmpty.class);
throw new IllegalAccessException(ne.message()); // 커스텀 메시지 출력
}
- 어노테이션이 적용된 에러 메시지 예시 이미지
1. Member member = new Member("지연", "");
2. validate(member) 호출
3. 리플렉션 → email 필드의 @NotEmpty 발견
4. setAccessible(true) → 값 읽기 → 빈값 확인
5. ne.message() → "이메일은 필수입니다" 예외 발생
| RetentionPolicy | 특징 | 용도 |
|---|---|---|
| SOURCE | 컴파일 후 사라짐 | @Override (컴파일러 검증) |
| CLASS | 바이트코드에 저장 | 런타임 접근 불가 |
| RUNTIME | JVM 메모리에 상주 | 리플렉션 처리 (스프링 기본) |
@Target({ElementType.FIELD, ElementType.METHOD})
스프링에서의 활용
@NotNull, @NotEmpty, @Size → 이미 구현된 어노테이션
@Valid + validate → 자동 검증
→ Controller에서 별도 validate() 호출 불필요
다음 단계: @Target 추가, 여러 어노테이션 조합, Spring Boot 연동
주의: 실전에서는 Hibernate Validator가 동일 기능 제공하므로 커스텀 어노테이션은 고급 요구사항에서만 사용한다.