반응형
커스텀한 어노테이션(Custom Annotation)이란 무엇일까? 그리고 우리가 주로 사용하는 어노테이션을 분석해보자
1. 커스텀 어노테이션을 만드는 방법
Java에서는 사용자 정의 어노테이션을 만들 수 있다. 이를 위해선 @interface 키워드를 사용하면 된다.
// @interface를 통해 어노테이션을 정의한다.
public @interface MyCustomAnnotation {
String value() default "";
int number() default 0;
}
- 위의 예제 코드에서, MyCustomAnnotation은 어노테이션의 이름이다.
- value와 number는 이 어노테이션의 요소(또는 매개변수)이며, 기본값으로 각각 빈 문자열과 0을 가지고 있다.
- 어노테이션 요소의 유형은 원시형, String, 클래스, 열거형, 어노테이션, 이들의 배열 등이 될 수 있다.
이렇게 만든 사용자 정의 어노테이션은 클래스, 메서드, 필드 등에 적용할 수 있다.
- 예를 들어 아래와 같이 내가 만든 어노테이션을 클래스 위에 적어주고 사용한다.
@MyCustomAnnotation(value = "Test", number = 10)
public class MyClass {
// ...
}
2. 메타 어노테이션
- 사용자 정의 어노테이션을 정의할 때는 다음과 같은 메타 어노테이션을 사용할 수 있다.
1. @Target
- 이 메타 어노테이션은 사용자 정의 어노테이션이 어떤 종류의 자바 요소에 적용될 수 있는지를 지정한다. ElementType의 값들을 사용하여 지정할 수 있다. 아래 코드는 MyMethodAnnotation이라는 사용자 정의 어노테이션을 만들었고, 이를 메소드에만 적용할 수 있게 했다.
@Target(ElementType.METHOD)
public @interface MyMethodAnnotation {
// ...
}
2. @Retention
- 이 메타 어노테이션은 사용자 정의 어노테이션의 수명을 지정한다. RetentionPolicy의 값들을 사용하여 지정할 수 있다.
- 아래 코드는 MyRuntimeAnnotation이라는 사용자 정의 어노테이션을 만들었고, 이 어노테이션을 런타임에도 유지하도록 설정했다.
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRuntimeAnnotation {
// ...
}
3. @Documented
- 이 메타 어노테이션은 사용자 정의 어노테이션을 Javadoc와 같은 문서에 포함시키는 지를 지정한다. 아래 코드는 MyDocumentedAnnotation이라는 사용자 정의 어노테이션을 만들었고, 이 어노테이션을 문서에 포함시키도록 설정했다.
@Documented
public @interface MyDocumentedAnnotation {
// ...
}
4. @Inherited
- 이 메타 어노테이션은 사용자 정의 어노테이션이 클래스 계층구조에서 하위 클래스로 상속되어야 함을 나타낸다.
- 아래 코드는 MyInheritedAnnotation이라는 사용자 정의 어노테이션을 만들었고, 이 어노테이션을 상속 가능하도록 설정했다.
- 이 어노테이션을 클래스에 붙이면, 해당 클래스를 상속하는 서브클래스들도 같은 어노테이션이 붙게 된다.
@Inherited
public @interface MyInheritedAnnotation {
// ...
}
3. 실제 우리가 주로 사용하는 @Controller 어노테이션 분석
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
- @Target({ElementType.TYPE}):
- 이 어노테이션은 이 사용자 정의 어노테이션이 어떤 Java 요소에 적용될 수 있는지를 지정한다.
- 여기서는 ElementType.TYPE을 지정함으로써, 이 어노테이션을 클래스, 인터페이스 (포함 프로토콜 인터페이스), 열거형, 어노테이션 타입에 적용할 수 있다.
- @Retention(RetentionPolicy.RUNTIME):
- 이 메타 어노테이션은 사용자 정의 어노테이션의 수명을 지정한다. RetentionPolicy.RUNTIME을 지정함으로써, 이 어노테이션은 런타임에도 유지되도록 설정된다. 이렇게 설정하면, JVM이 실행 중일 때 어노테이션을 읽을 수 있다.
- 이 메타 어노테이션은 사용자 정의 어노테이션의 수명을 지정한다. RetentionPolicy.RUNTIME을 지정함으로써, 이 어노테이션은 런타임에도 유지되도록 설정된다. 이렇게 설정하면, JVM이 실행 중일 때 어노테이션을 읽을 수 있다.
- @Documented:
- 이 메타 어노테이션은 사용자 정의 어노테이션을 Javadoc과 같은 문서에 포함시키는지를 지정한다.
- 이 어노테이션을 사용함으로써, 이 사용자 정의 어노테이션이 문서에 포함된다.
- @Component:
- 이 어노테이션은 Spring에서 관리하는 빈으로 등록하겠다는 표시이다.
- 여기서는 @Controller 어노테이션을 Spring의 빈으로서 관리하겠다는 의미로 @Component를 사용하고 있다.
- public @interface Controller:
- 이것은 Controller라는 이름의 사용자 정의 어노테이션을 정의하는 부분이다.
- 이것은 Controller라는 이름의 사용자 정의 어노테이션을 정의하는 부분이다.
- @AliasFor(annotation = Component.class):
- @AliasFor 어노테이션은 메타 어노테이션 요소의 별칭을 선언하는 데 사용된다.
- 여기서는 Component 어노테이션의 value 속성의 별칭으로 사용된다.
- String value() default "";:
- value는 이 사용자 정의 어노테이션의 요소이다.
- 기본값으로 빈 문자열("")이 설정되어 있다. 이 value 요소는 Spring에서 빈의 이름을 설정하는 데 사용된다.
여기서 주목해야 할 것은, 이 @Controller 어노테이션은 사용자가 직접 정의한 것이 아니라, Spring 프레임워크에서 제공하는 어노테이션이다. 이 코드는 그 원리를 설명하기 위해 @Controller 어노테이션의 코드가 어떻게 생겼는지를 가상으로 보여주는 것일 뿐, 실제로 이렇게 작성해야 하는 것은 아니다.
4. 추가정보 - 런타임이란?
런타임
- "런타임(runtime)"은 프로그램이 실행되는 시점, 즉 코드가 컴파일된 후 실제로 실행되고 있는 동안을 말한다.
- 이는 프로그램의 수명 주기 중에 컴파일 타임(소스 코드가 기계어로 번역되는 시점)과 대비되는 개념이다.
- "런타임"은 프로그램이 실제로 작동하고 있는 시점을 가리키는 말이며, 이 시점에서는 변수 할당, 조건문 평가, 예외 처리 등 많은 동작이 발생한다.
스프링 컨테이너가 관리하는 어노테이션에 RetentionPolicy.RUNTIME을 붙이는 이유는?
- 예를 들어, Spring 프레임워크는 @Component, @Service, @Repository, @Controller 등의 어노테이션을 사용하여 Bean을 찾고, 이들을 Spring IoC 컨테이너에 등록한다.
- 이런 작업은 프로그램이 실행되는 동안, 즉 런타임에 일어나기 때문에 이런 어노테이션들은 RetentionPolicy.RUNTIME으로 설정되어 있다.
- 이렇게 설정함으로써 Spring은 런타임에 어노테이션 정보를 읽어서 필요한 작업을 수행할 수 있다.
2023.08.08 - [Spring 기초/spring 어노테이션] - Spring Boot 기초: 어노테이션 활용하기 (1편)
반응형
'Spring 기초 > Spring 기초 지식' 카테고리의 다른 글
Spring Boot 폼 데이터 바인딩: @ModelAttribute 활용법 (0) | 2023.08.09 |
---|---|
Spring Boot에서 REST 컨트롤러 활용하기: @RestController 어노테이션 이해하기 (0) | 2023.08.08 |
Spring Boot 기초: 어노테이션 활용하기 (1편) (0) | 2023.08.08 |
Spring Framework 이해하기: 다형성, 개방-폐쇄 원칙(OCP), 인터페이스 활용의 장점 (0) | 2023.08.08 |
@ControllerAdvice, @RestControllerAdvice - 중앙집중 예외처리 (0) | 2023.08.07 |