어노테이션
스프링이나 스프링부트를 사용하다보면 여러 어노테이션들을 마주할 수 있습니다.
@Service //어노테이션 예시
그러면 스프링에서는 아 얘가 Service구나 파악을 하고 관리해주겠죠. 저는 그래서 이런 어노테이션은 곧 메서드랑 비슷하구나 생각을 했었습니다.
그러나 찾아보니 어노테이션이라는 단어 자체는 주석이라는 뜻을 가지고 있다고 합니다. 주석과 비슷하면서도 다른 점이 존재하는데, 그것은 뭔가 특별한 기능을 제공한다는 점에서 차이가 있습니다. 어노테이션을 붙인 메서드나 클래스에는 별 다른 기능을 제공하지 않는다고 합니다. 다만 다른 곳에서 이 프로그램을 인식하기 쉽게 정보를 제공해준다고 합니다. 이게 특별한거죠.
아까 예시처럼 @Service를 붙인 BoardService가 있다고 해볼게요. 이 BoardService 클래스에서는 아무 영향을 끼치지 않습니다. 그러나 스프링에서는 얘가 Service라는 것을 인식하게 해주는 메타 데이터의 역할을 어노테이션이 수행합니다.
어노테이션 정의하는 방법
public @interface Mine {
}
어노테이션은 위의 방식처럼 정의할 수 있습니다. 일반 인터페이스(interface)와 어노테이션을 구분하기 위해서 앞에 골뱅이(@)를 붙여줘야합니다.
어노테이션 요소
어노테이션에 필드같은 요소를 정의할 수 있습니다. 요소의 타입은 기본형, String, Enum, 어노테이션, 클래스만 허용됩니다. 매개변수와 예외는 쓸 수 없습니다. 디폴트 값을 선언할 수 있습니다.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Mine {
String value() default "hello";
}
@Retention
어노테이션 유지 관련해서 사용합니다.
- SOURCE: 어노테이션을 사실상 주석처럼 사용함. 컴파일할때까지 살아있음
- CLASS: 런타임시에 사라짐(런타임 직전까지 생존)
- RUNTIME: 런타임시에도 사용가능
@Target
어노테이션 적용 대상을 지정합니다. 일반적으로는 메서드에만 사용가능한 METHOD 옵션이나 class, interface, annotation, enum 등에 적용 가능한 TYPE 옵션을 사용합니다.
@Documented
해당 어노테이션 정보를 자바독스(JavaDocs)에 포함되도록 해줍니다.
@Inherited
자식 클래스에서 부모 클래스의 어노테이션 사용이 가능하다고 명시해줍니다.
어노테이션 예시와 함께 보느니라고 설명할 타임을 놓쳤는데 Retention부터 Inherited까지 얘네들을 어노테이션을 위한 어노테이션 즉 메타어노테이션이라 부릅니다.
표준 어노테이션
앞에서 설명한 메타 어노테이션과 달리 자바 코드에 사용할 수 있는 어노테이션들을 설명드릴게요.
@Override
오버라이를 할 때 사용되는 어노테이션입니다. 이 어노테이션이 없어도 오버라이드는 가능하지만 실수 방지를 위해서라도 붙여주는 편이 좋습니다.
@Deprecated
앞으로 사용되지 않을 대상에 붙여지는 어노테이션입니다. 보통은 버전이 변경되면서 사용되지 않을 대상들에 붙습니다. 저는 대체로 버전업이 되면서 이 어노테이션이 붙으면 괜히 이 어노테이션을 붙이지는 않았을거라고 생각해서 다른 권장하는 방법이 있는지 살펴보는 편입니다.
@SupressWarnig
경고를 띄우지 말라고 알려주는 어노테이션입니다. 의도적으로 경고가 생기는 코드를 작성하면 컴파일러 입장에서는 무조건 경고를 보여주겠죠. 하지만 난 알고 그런거니까 경고 없애라!! 라고 알려주는 어노테이션입니다.
@FunctionalInterface
함수형 인터페이스를 설계할때 사용하는 어노테이션입니다. 사용해본 적이 없어서 무슨 의미인지는 감이 안잡힙니다만.. 자료 조사를 해보니까 함수형 인터페이스에는 메서드가 딱 하나만 존재해야 된다고 해요. 그러면 특정 인터페이스 자체를 메서드처럼 사용하겠다는건가..?? 뭐 이런 생각이 듭니다. 쓰레드를 설명하면서 언급한 Runnable이 대표적인 예시라고 해요.
함수형 인터페이스의 이득에 대해서는 잘 설명한 글을 링크 걸어둘게요.
https://woowacourse.github.io/javable/post/2020-07-17-Functional-Interface/
어노테이션 프로세서
완전 처음 접하는 용어이지만 제가 이미 사용중인 롬복이 여기에 해당한다고 합니다. 컴파일 단계에서 개발자가 정의한 소스를 처리하는 기술이라고 합니다. 단순히 컴파일 에러나 경고를 표시해주기도 하며 소스 코드에 무언가를 추가해주기도 합니다. 롬복의 @Getter와 @Setter가 후자에 해당되겠네요.
참고
자바의 정석
자바 공식 문서
'Java' 카테고리의 다른 글
추상클래스의 객체 생성 (0) | 2023.10.29 |
---|---|
[JAVA] Enum 열거형 정리 (0) | 2021.06.07 |
[JAVA] 멀티쓰레드 프로그래밍 (0) | 2021.06.02 |
[Java] 예외처리 (0) | 2021.05.18 |
[Java] 인터페이스에 대하여 (0) | 2021.05.10 |