[강의] Java Annotation

Jerry·2025년 7월 10일

Topic

Annotation

What I Learned

Annotation

정의

  • 코드에 메타데이터(정보)를 추가하여 컴파일러, 개발 도구, 프레임워크에서 특정한 의미나 동작을 지시하는 기능
  • @Override, @SuppressWarnings처럼 컴파일러나 런타임 동작에 영향을 줄 수 있는 지시자 역할
  • 리플렉션을 통해 추출하거나, 커스텀 어노테이션으로 사용자 정의도 가능하다.
// 컴파일 어노테이션 예시
@Override
public String toString() {
	return"Hello";
}
@SuppressWarnings("unchecked")
List<String> list = new ArrayList();
// Spring 어노테이션 예시
@RestController
public class HelloController {
	@GetMapping("/hello")
	public String sayHello() {
		return "Hello, Spring!";
	}
}

주요 시스템 어노테이션

  • @Override 메소드 부모 클래스의 메소드를 오버라이딩했는지 검사
  • @Deprecated 클래스, 메소드, 필드 등 해당 요소의 사용을 권장하지 않음을 표시
  • @SuppressWarnings 클래스, 메소드 등 컴파일러의 특정 경고를 억제 (unchecked, deprecation 등)
  • @SafeVarargs 메소드, 생성자 (varargs) 제네릭 가변 인자에 대한 경고 억제 (Java 7+)
  • @FunctionalInterface 인터페이스 함수형 인터페이스(메소드 1개만 가짐)임을 명시 (Java 8+)
  • @interface 어노테이션 선언 해당 선언이 어노테이션 인터페이스임을 컴파일러에 알림
  • @Retention 어노테이션 선언 어노테이션의 유지 범위를 지정 (SOURCE, CLASS, RUNTIME)
  • @Target 어노테이션 선언 어노테이션의 적용 대상을 지정 (METHOD, TYPE)
  • @Documented 어노테이션 선언 Javadoc에 표시되도록 지정
  • @Inherited 어노테이션 선언 자식 클래스가 어노테이션을 상속받을 수 있게 함
  • @Repeatable 어노테이션 선언 어노테이션을 반복 사용할 수 있도록 허용

커스텀 어노테이션

정의

  • 직접 정의한 메타데이터로 코드에 부가 정보를 제공하기 위해 사용된다.
// 정의
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
	String value();
}

// 활용
@MyAnnotation(value = "test")
public class TestClass {
	...
}

// 선언 값 가져오기
TestClass test = new TestClass();

MyAnnotation annotation = test.getClass().getAnnotation(MyAnnotation.class);
System.out.println(annotation.value()); // test

다중 인자 활용

// 정의
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnno {
	String name();
    int count() default 1;
    boolean active();
    String[] tags() default {};
}

// 활용
@MyAnno(name = "Hello", count = 3, active = true, tags = {"a", "b"})
public class TestClass {}

@Retention

@Retention(RetentionPolicy.[value]
SOURCE 컴파일 시 사라짐 (ex. @Override)
CLASS 클래스 파일까지 유지되나 JVM에서 읽지 않음
RUNTIME 런타임에도 유지되어 리플렉션으로 접근 가능

@Target

Target({ElementType.[value], ElementType.[value]})
TYPE 클래스, 인터페이스, 열거형
METHOD
FIELD
CONSTRUCTOR
PARAMETER
LOCAL_VARIABLE
ANNOTATION_TYPE
TYPE_USE 타입 선언 위치 전체 (Java 8+)
TYPE_PARAMETER 제네릭 선언의 타입 매개변수 (Java 8+)

Custom Annotation의 역할

역할설명
메타데이터 부착클래스, 메서드, 필드 등에 추가 정보를 부여함
프레임워크 설정스프링 등 프레임워크에서 @Controller, @Autowired 같은 동작 지정
검증 로직 처리@NotNull, @Email 등으로 유효성 검사를 선언적으로 표현
코드 생략 및 간결화설정/로직을 코드가 아닌 애너테이션으로 표현하여 가독성 증가
런타임 처리 지시AOP, DI, ORM 등에서 런타임 중 동작 변경 가능

리플렉션(Reflection)과의 관계

Custom Annotation은 리플렉션으로 읽어서 동작합니다. 자바 컴파일 시 애너테이션은 .class 파일에 저장되고, 런타임 시 Class, Method, Field 등의 객체를 통해 애노테이션을 탐지하고 동작 제어합니다.

예시

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyLog {
    String value() default "로그 출력";
}
public class MyService {
    @MyLog("실행됨")
    public void process() {
        System.out.println("업무 처리");
    }
}
// 리플렉션으로 애너테이션 확인
Method method = MyService.class.getMethod("process");
if (method.isAnnotationPresent(MyLog.class)) {
    MyLog annotation = method.getAnnotation(MyLog.class);
    System.out.println("로그: " + annotation.value()); // → 로그: 실행됨
}

프레임워크와의 연관

프레임워크들은 리플렉션을 통해 custom annotation을 스캔하고 특정 동작을 수행합니다.

  • Spring: @Autowired, @RequestMapping → 빈 주입 및 라우팅
  • JPA: @Entity, @Id → 테이블 매핑
  • Validator: @NotNull, @Email → 런타임 검증
  • AOP: @Transactional, @LogExecution → 동적 프록시 처리
profile
Backend engineer

0개의 댓글