개요
스프링 부트에는 annotation 관련 기능을 많이 제공하고 있는데 저 포함 많은 개발자가 동작 방식을 자세히 모르는 상태로 개발을 하고 있는 것 같습니다.
스프링에서 기본으로 제공하는 애노테이션 같은 경우 동작 원리를 모르는 상태로 사용해도 개발하는데 문제없지만 커스텀하게 애노테이션을 선언해야 할 경우 문제가 발생할 확률이 큽니다.
따라서 이번 게시글에서는 간략하게 스프링에서 제공하는 메타 애노테이션과 더불어 합성 애노테이션에 대해 알아보겠습니다.
메타 애노테이션(Meta-annotation)
메타 애노테이션은 애노테이션에 적용한 애노테이션을 의미합니다.
예를 들자면, @Controller 애노테이션이 부여된 클래스는 @Controller의 메타 애노테이션인 @Component가 직접 사용된 것처럼 Component Scan의 대상이 됩니다.
스프링에서 제공하는 메타 애노테이션은 기본적으로 @Target과 @Retention이 있는데 커스텀 애노테이션을 정의하기 위해서는 우선 이 둘에 대해 알아야 합니다.
@Target
- 자바 컴파일러가 해당 애노테이션이 어디에 적용될지 결정하기 위해 사용
- @Controller처럼 ElementType.TYPE일 경우 타입 선언 시 사용된다는 것을 의미하며 ElementType.CONSTRUCTOR일 경우 생성자 선언 시 사용된다는 것을 의미
- 더 자세한 내용은 아래 enum 클래스 참고
@Retention
- 애노테이션이 실제로 적용되고 유지되는 범위를 의미
- 종류는 RUNTIME, CLASS, SOURCE로 나뉘며 보통 컴파일 이후에도 JVM에서 참조할 수 있도록 RUNTIME으로 지정
- RUNTIME 적용 시 Reflection 혹은 Logging에 주로 사용
RetentionPolicy | 설명 |
RUNTIME | 컴파일 이후에도 JVM에 의해서 참조 가능 |
CLASS | 컴파일러가 클래스를 참조할 때까지 유효 |
SOURCE | 컴파일 전까지만 유효 |
메타 애노테이션 적용 시 장점
- Meta Annotation이 붙은 클래스와 애노테이션이 적용된 클래스와 기능적 차이는 없지만 다른 이름을 부여함에 따라 가독성을 높여줌
- 우리가 코드를 읽을 때 이 클래스는 Spring의 빈으로 등록되는 것이구나 뿐만 아니라 이 것은 Spring MVC의 Controller 역할을 하는구나라는 부가정보를 얻을 수 있음
- 부가 효과도 기대할 수 있는데 @Controller가 붙어있으면 DispatcherServlet으로 하여금 해당 클래스가 WebController로 사용되는 것과 애노테이션을 이용한 매핑 정보가 있다는 것을 판단하여 @RequestMapping 탐색하도록 유도
- 새로운 애노테이션 구현 시 메타 애노테이션에는 없는 새로운 element 추가 가능 (확장성)
* 주의: 메타 애노테이션이 상속처럼 보일 수 있지만 사실 상속은 아님
- 모든 애노테이션에는 Retention과 Target 부여 필요
- 애노테이션이 적용될 수 있는 위치가 많은데 그중에서 Element.TYPE만 메타 애노테이션이 될 수 있음
합성 애노테이션
합성 애노테이션은 하나 이상의 메타 애노테이션이 적용된 annotation을 의미합니다.
반복적으로 여러 메타 애노테이션을 동시에 사용할 경우 코드가 지저분해 보일 수 있으므로 합성 애노테이션을 별도로 정의함에 따라 코드를 비교적 깔끔하게 정리를 할 수 있습니다.
합성 애노테이션을 적용한다고 해서 별도 기능이 추가되는 것이 아니고 합성 애노테이션에 적용된 모든 애노테이션이 적용된 것과 동일한 효과를 갖기 때문에 순전히 가독성 때문에 사용한다고 보시면 됩니다.
예를 들자면, @RestController의 경우 @Controller와 @ResponseBody를 둘 다 사용한 것과 동일한 결과를 가져옵니다.
참고
인프런 토비의 스프링 부트 - 이해와 원리
https://sanghye.tistory.com/39
'Spring' 카테고리의 다른 글
[Spring] @Conditional 정리 (2) | 2023.03.07 |
---|---|
[Spring Boot] AutoConfiguration (0) | 2023.03.06 |
Spring 지원 없이 Servlet을 통해 Front Controller 구현 (0) | 2023.03.02 |
Spring Boot 개요 (0) | 2023.02.27 |
[SpringBoot] 구글 SMTP 통해 메일 보내기 (2) | 2022.04.10 |