|
SSISO Community검색 |
|
SSISO Community메뉴 |
|
SSISO Community카페 |
|
블로그 카테고리 |
|
|
Synchronized로 검색한 결과 |
|
등록일:2008-03-12 10:20:37 작성자: 제목:Annotation과 Reflection, 그리고 코드 속의 MetaData |
|
Annotation과 Reflection, 그리고 코드 속의 MetaData
Q: Annotation 이란 무엇인가?
A: Annotation = 주석 (뇌이버 사전 왈)
물론 아주 틀린 말은 아니다.
사실 주석이 맞지 않은가? comment 랑 비슷한 의미로 생각해라.
하지만 자바에서 Annotation 이라는 건 주석 그 이상의 의미를 갖는다.
무슨 의미인가 하면... Annotation은 런타임 시에도 특정 메소드를 사용하여 읽을 수 있다는 것이다.
Annotation의 역사
자바 SE 5 (1.5) 부터 추가된 기능으로 JSR 175가 구현됨으로써 세상의 빛을 보기 시작했다.
JSR 175가 2002년에 JSR에 소개되고 2004년 가을에 모습을 드러냈으니 역사가 겨우 5년밖에 안된 셈이다.
참고: Wikidipia (흔히 위키신으로 알려진...)
Annotation의 사용법
패키지명이나 클래스 선언, 메소드 선언, 필드 선언, 인자값 선언 앞에다가 다음을 붙인다.
@이름(인자)
인자가 없을 경우 괄호는 생략 가능하다.
Annotation의 선언 방법
선언은 다음과 같이 한다. (Annotation은 인터페이스의 변형이다.)
@Retention(용도)
@Target(범위)
public @interface 이름
{
T 메소드명();
...
}
별도의 인자값이 필요한 경우 메소드를 선언하면 된다.
물론 인터페이스 기반이므로 메소드를 선언하더라도 구현은 필요 없다.
참고로 용도와 범위는 반드시 선언되어야 한다. (범위는 여러 개를 동시에 선언할 수 있다.)
Annotation의 용도
RetentionPolicy에 세 가지의 용도가 선언되어있다.
이름 범위
SOURCE
컴파일러가 사용하고 클래스 파일 안에 포함되지 않음
(단순 주석용, 컴파일러용)
CLASS 컴파일시 클래스 파일 안에 포함되나 VM에서 무시함
RUNTIME 컴파일시 포함되고 VM에서 인식함
단 하나의 용도만 선택이 가능하다.
Annotation의 범위
ElementType에 8가지의 범위가 선언되어있다.
선언되지 않은 범위에 Annotation을 사용할 경우 해당 Annotation은 무시된다.
이름
범위
TYPE 클래스, 인터페이스, Annotation, 또는 열거형 타입
FIELD 필드 또는 열겨형 타입의 값
METHOD 메소드
PARAMETER 메소드의 인자
CONSTRUCTOR 클래스 생성자
LOCAL_VARIABLE 메소드 내부 변수
ANNOTATION_TYPE Annotation 타입
PACKAGE 패키지
타겟은 여러 개가 선택될 수 있다.
배열이기 때문에 여러 개를 선택할 경우 중괄호로 포장해주는 것을 잊지 말자.
예를 들면 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
그런데... Reflection은 갑지기 왜?
자바 런타임에 Annotation이 추가되면서 제일 많이 변화된게 바로 Reflection 관련 패키지들이다.
Reflection은 사전에 검색해봐야 "반사!" 밖에 안나오니까 무시하고...
(갑자기 초딩들 언어유희가 생각나는데...)
Q: 그러면 프로그래밍 언어에서 Reflection은 무엇인가?
A: a instanceof b (어떤 언어 - 예를 들어 파스칼 계열 -는 a is b) 가 괜히 컴파일 된다고 생각하는건가?
프로그래밍 언어에서 Reflection은 어떠한 오브젝트 (본인은 객체라고 안하고 그냥 오브젝트라고 밀고 나간다.) 의 본질을 찾아가는 패키지이다.
Reflection으로 해당 오브젝트의 클래스 선언 정보, 클래스의 패키지 위치, 메소드 목록, 필드 목록, 메소드의 인자 목록들이 줄줄이 비엔나 소시지 모양으로 나오니 잘쓰면 강력한 툴이며, 모르면 평생 모르는 채로 살게 된다.
(왜 모른 채로 살게 되냐고? 이거 설명한 책이 이상하게도 거의 없다! Manning에서 나온 Java Reflection in Action이 내가 찾아낸 유일한 책이다.)
그러면 Reflection에 무슨 변화가 일어났는가?
바로 이 Reflection이 Annotation을 읽을 수 있도록 메소드가 추가되었다는 말이다.
Annotation + Reflection = 코드 속의 MetaData
이걸 어디다 쓰냐고 묻고 싶은 사람들이 있을 것인데... 힌트를 주겠다.
switch문 도배 지겹지?
if...else... 로 두 페이지 채우는거 지겹지?
이제 좀 감이 잡혔을 것이라고 본다.
아래는 내가 진행했던 모 프로젝트에 들어간 코드의 일부분이다.
switch문을 날려버리고 메세지 타입에 따라 자동으로 해당 메소드로 찾아가는 부분인데...
private static final Map<MessageType, Method> MethodTable = new HashMap<MessageType, Method>();
static {
// Annontation 달린 메소드들만 추출
for (Method m : AgentInterface.class.getDeclaredMethods()) {
if (m.isAnnotationPresent(ProcessMessageType.class)) {
MethodTable.put(m.getAnnotation(ProcessMessageType.class).value(), m);
}
}
}
private Synchronized void processInput(InternalMessage im) {
// null 이면 무시
if (im == null || im.Type.equals(MessageType.Unknown)) {
return;
}
// 메세지 종류별 처리
try {
MethodTable.get(im.Type).invoke(this, im);
} catch (Exception e) {
e.printStackTrace();
}
}
소스 설명 요청은 정중히 사절하겠다.
[출처] Annotation과 Reflection, 그리고 코드 속의 MetaData|작성자 강신영
http://blog.naver.com/kang594?Redirect=Log&logNo=39704853 |
|
|
|
|
|