본문 바로가기
java

[Java] 어노테이션 - xml을 벗어나자

by jinbro 2017. 9. 21.
[어노테이션]
(1) 사전정의로는 주석이지만 자바에서는 주석 이상의 역할을 함
(2) 메타데이터 역할
- 컴파일, 런타임에서 어노테이션이 붙은 코드에 대해서 어떻게 처리할지 정보를 줌
- 사전에 세팅시키는 데이터와 로직을 분리시킬 수 있음
- 리스너 연결 같은 류의 중복되는 코드를 줄일 수 있음 
- 활용 예제 그리고 써보면서 어노테이션에 대해서 더 알아보겠음


(3) 어노테이션 종류
1) 기본 제공 어노테이션
- @Override : 슈퍼 타입의 메서드를 오버라이딩할 때 기본적으로 세팅되며, 컴파일러가 정확하게 오버라이딩 됐는지 체크함
- @SuppressWarnings : 실행에는 문제없지만 컴파일 과정에서 뿜는 메세지를 보기 싫을 때 어노테이션 처리해두면 안뿜음
- @Deprecated : 더 나은 대안이 있다는 표시, 컴파일러가 경고 표시함


2) 사용자 정의 어노테이션
- java.lang.annotation.Annotation.java(인터페이스) 상속받음
- IDE에서 Annotation 파일 생성 : @inteface 어노테이션명 - 특별한 interface
- 메서드 선언 : interface 라서 구현부 없음
- 기본적으로 설정할 수 있는 메서드 : String value()가 있음, 생략가능함

2-1) 사용자 정의 어노테이션 - 특정 코드에 대한 메타데이터 세팅
- 어노테이션 정의할 때 @Target(타겟_열거상수)로 설정
- Target Enum : java.lang.annotation.ElementType 참고
- @Target 선언 시 다수 타겟 설정 가능

2-2) 사용자 정의 어노테이션 - 메타데이터 유지 기간 설정
- 어노테이션 정의할 때 @Retention(유지기간_열거상수)로 설정
- Retention_Enum : java.lang.annotation.RetentionPolicy 참고
- @Retention 선언 시 1개만 설정
/* java.lang.annotation.Annotation 상속받음 */
package com.jinbro.source;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface Jinbro {
//primitive, reference(string + enum + 사용자정의) 데이터
public String value(); //default element (String return type abstract method)
public String name();
public int age() default 0;
}


(4) 리플렉션으로 코드에 적용된 어노테이션 가져오기
- 리플렉션 : 런타임 때 로드 되어있는(메모리 메서드 영역) 클래스 정보를 가져올 수 있음
1) 패키지명
2) 클래스 풀네임
3) 메서드/필드 등 목록
4) 추가 - 적용된 어노테이션 목록(Class<? extends Annotation> annotaionClass) 
- 선언되어있지않은 어노테이션 클래스를 getAnnotation 인자로 넘겨주면 NullPoiterException
- 리플렉션 제공하는 isAnnotationPresent로 어노테이션 적용 여부를 알 수 있음
- 소스 - 컴파일 - 런타임 : 메서드 영역에 로드되어있음 - static 블록에서 사용됨 

5) 활용하기
- 어노테이션이 적용된 코드만 로직 수행
- 어노테이션(기본값 or @어노테이션(메서드=값))에 값 리턴받아서 로직 수행에 사용
/* Annotation 사용 */
package com.jinbro.source;

import java.lang.reflect.Method;

public class AnnotationTest {

public AnnotationTest(){}

@Jinbro(value = "기본1", name="jinbro")
public void test1(){}

@Jinbro(value = "기본2", name="jinhyung")
public void test2(){}
public static void main(String[] args) {
//어노테이션 클래스를 로딩하는게 아니라 어노테이션이 적용된 클래스를 불러옴
Method[] methods = AnnotationTest.class.getMethods();
for(Method m : methods){
if(m.isAnnotationPresent(Jinbro.class)){
Jinbro jinbro = m.getAnnotation(Jinbro.class);
System.out.println(jinbro.name()); // jinbro jinhyung

/*
[활용하기]
1) 어노테이션이 적용된 코드만 로직 수행
2) 어노테이션(기본값 or @어노테이션(메서드=값))에 값 리턴받아서 로직 수행에 사용
*/
}
}

}
}



댓글