자바(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

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

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