자바(SE)

Annotation(에너테이션) 사용법

  • -

Annotation

Annotation은 Java 1.5에 추가된 녀석으로 지금은 새로울게 없지만 당시만해도 이거뭐하는거야 했던 녀석이다. 

Annotation이란?

Annotation의  사전적 의미는 주석이라는 뜻인데 다만 우리를 위한 주석은 아니고 컴파일러나 JVM, 프레임워크 등이 보는 주석이다.

즉 코드상에 annotation을 달아놓으면 상황에 따라 컴퍼일러가 읽어서 무슨 처리를 하고 프레임워크가 읽어서 무슨 처리를 하는 형태이다.

흔히 이제까지 봐왔던 annotation으로는 @Override나 @Deprecated등이 있다.

@Override라고 쓰고 override 문법을 지키지 않으면 컴파일 시 오류가 발생하고 이클립스에서도 오류가 표시되는 것을 경험한 적이 있을 것이다. @Deprecated가 선언된 메서드를 사용하려 하면 역시 이클립스가 읽어서 취소선을 쫙 그어준다.

@Deprecated
public String helloEng(String name) {
    return "Hello " + name;
}

아무튼 이렇게 보조적인 역할을 하던 annotation이 스프링에서는 프로그래밍에 아주 적극적으로 사용된다. 그래서 잘 사용하지 못하면 혼돈의 늪에 빠지기 쉽다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/mvc-config.xml"})
@WebAppConfiguration
public class RequestMappingTest {
    @Autowired
    WebApplicationContext ctx;
 }

 

이번 포스트에서는 annotation을 어떻게 분석하고 사용해야 하는지 살펴보자.

 

Annotation 분석

 

에너테이션의 구성

에너테이션은 메타 에너테이션과 에너테이션 선언, 에너테이션 속성 정의의 3 부분으로 이뤄진다. 예를 들어 다음은 SupressWarnings라는 애너테이션의 소스 코드이다.

 

메타 에너테이션이란 에너테이션에 선언된 에너테이션들로 애너테이션 설정과 관련된 내용을 담는다.

에너테이션을 선언할 때는 @interface 키워드를 이용한다.

에너테이션 속성은 에너테이션을 사용할 때 전달해야하는 속성들을 나열한다.

 

메타 에너테이션

meta annotation이란 에너테이션에 선언된 에너테이션으로 에너테이션 사용과 관련된 정보를 제공한다.

모든 애너테이션에는 @Retnetion과 @Target이 선언되어있다. 

먼저 @Retention은 에너테이션이 얼마나 오래동안 에너테이션 정보를 유지할 것인지를 설정한다. @Retention에는 RetentionPolicy를 이용해서 이 기간을 선언할 수 있는데 RetentionPolicy에 상수로 정의되어있다.

상수값 범위
SOURCE 컴파일러가 사용하며 컴파일 결과물인 클래스 파일 안에는 포함되지 않음
CLASS 컴파일 시 클래스 안에 포함되지만 VM에서는 무시되며 reflaction 시에는 정보를 얻을 수 없다.
RUNTIME 컴파일 시 포함되며 VM에서 인식하며 feflaction 시 정보를 얻을 수 있다.

@Retention 정보는 사실 사용하는 입장에서는 그다지 중요하지 않은것 같다.

@Target은 매우 중요한 속성인데 에너테이션을 어디에서 사용할 수 있는지 지정한다. @Target에서 사용 가능한 속성들은 ElementType에 상수값으로 선언되어있는데 아래와 같다.

상수값 범위
TYPE 클래스, 인터페이스 또는 enum 타입
FIELD 필드 또는 enum 타입의 값
METHOD 메서드
PARAMETER 메서드의 파라미터
CONSTRUCTOR 생성자
LOCAL_VARIABLE 로컬 변수
ANNOTATION_TYPE 다른 에너테이션
PACKAGE 패키지

예를 들어 아래와 Qualifier라는 에너테이션을 살펴보자.

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, 
         ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {

	String value() default "";

}

@Qualifer의 @Target에 살펴보면 FIELD, METHOD, PARAMETER, TYPE, ANNOTATION_TYPE에 사용될 수 있는 에너테이션이기 때문에 생성자에는 사용할 수 없다는 것을 알 수 있다.

 

에너테이션의 속성

에너테이션에는 미리 지정된 속성에 값을 전달할 수 있다. 그런데 경우에 따라 다양한 형태로 값이 전달되므로 주의가 필요하다.

일단 속성은 마치 추상 메서드 처럼 선언하고 일반 속성처럼 key=value 의 형태로 사용한다.이때 메서드의 이름은 속성의 이름이 되고 리턴 타입은 속성의 타입이다.

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, 
         ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {

	String value() default "";

}

위 @Qualifier에는 value라는 속성이 선언되어있으며 타입은 문자열이다. default 로 "" 이 할당되기 때문에 반드시 값을 할당할 필요는 없다.

속성 사용시 주의할 사항은 아래와 같다.

  • 설정하려는 속성이 value 하나인 경우는 속성 이름인 value를 생략할 수 있다.
  • 타입은 일반 자바 타입을 사용할 수 있으며 배열의 길이가 1일 때는 {}를 생략할 수 있다.

아래와 같이 ComponentScan 에너테이션을 사용할 때 잘못 선언된 것들을 찾아보자.

 

 

'자바(SE)' 카테고리의 다른 글

[Java]Thread의 선/후 작업과 CountDownLatch  (0) 2021.02.16
Comparing identical expressions  (0) 2021.01.16
밑이 2인 로그 구하기  (0) 2020.10.16
Comparator의 default method chaining  (0) 2020.08.13
List에서의 자료 삭제  (0) 2020.08.11
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.