3. 자바 리플렉션으로 어노테이션 다루기
자바 리플렉션을 사용함으로서 런타임에 자바클래스에 정의되있는 어노테이션 정보에 접근할수있다.
클래스 어노테이션
Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
요렇게 접근가능하다:
Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
Method 어노테이션
public class TheClass {
@MyAnnotation(name="someName", value = "Hello World")
public void doSomething(){}
}
요렇게 접근가능하다:
Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
요렇게도 접근가능하다:
Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
Parameter 어노테이션
public class TheClass {
public static void doSomethingElse(
@MyAnnotation(name="aName", value="aValue") String parameter){
}
}
요렇게 접근가능하다:
Method method = ... //obtain method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();
int i=0;
for(Annotation[] annotations : parameterAnnotations){
Class parameterType = parameterTypes[i++];
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("param: " + parameterType.getName());
System.out.println("name : " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
}
Method.getParameterAnnotations() 메소드는 2차원 배열을 리턴한다는걸 주목하라.
그것은 메소드파라미터 각각의 어노테이션 배열을 포함한다.
Field 어노테이션
public class TheClass {
@MyAnnotation(name="someName", value = "Hello World")
public String myField = null;
}
요렇게 접근가능하다:
Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
}
요렇게도 접근가능하다:
Field field = ... // obtain method object
Annotation annotation = field.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value: " + myAnnotation.value());
}
Annotation & Reflection 예제
* 메타 annotation type
1.@documented : 이 어노테이션을 자바독이나 유사한 도구로 문서화되어져야하는데 사용
하는 엘리먼트를 지칭
2.@Target : 어노테이션 타입이 수용할 수 있는 많은 프로그램 엘리먼트를 지칭
3.@Inherited : 자동으로 상속받는 어노테이션 타입을 지칭
4.@Retention : 어노테이션된 타입이 얼마나 지속되는가를 지칭
[메소드에 지정할 어노테이션 정보들을 정의해놓은 인터페이스]
- package com.journaldev.annotations;
- import java.lang.annotation.Documented;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Inherited;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- @Documented
- @Target(ElementType.METHOD)
- @Inherited
- @Retention(RetentionPolicy.RUNTIME)
- public @interface MethodInfo {
- String author() default "Pankaj";
- String date();
- int revision() default 1;
- String comments();
- }
[어노테이션을 적용한 메소드들이 정의되어 있는 클래스 예]
- package com.journaldev.annotations;
- import java.io.FileNotFoundException;
- import java.util.ArrayList;
- import java.util.List;
- public class AnnotationExample {
- public static void main(String[] arg) {
- }
- @Override
- @MethodInfo(comments = "deprecated method",
- date = "Nov 17 2012",
- revision=1)
- public String toString() {
- return "Overriden toString method";
- }
- @Deprecated
- @MethodInfo(comments = "deprecated method",
- date = "Nov 17 2012")
- public static void oldMethod() {
- System.out.println("old method, don't use it.");
- }
- @SuppressWarnings({"unchecked", "deprecation"})
- @MethodInfo(author = "Pankaj",
- comments = "Main method",
- date = "Nov 17 2012",
- revision = 10)
- public static void genericsTest() throws FileNotFoundException {
- List list = new ArrayList();
- list.add("abc");
- oldMethod();
- }
- }
[Reflection을 사용하여 어노테이션 정보를 분석하는 클래스 :
테스트 클래스로 클래스의 모든 메소드를 로드하고, 그 메소드 중에 어노테이션 인터페이스
에 정의된 어노테이션을 마킹한 각 메소드에 한해서만 이하 작업을 수행.]
1.해당 메소드의 모든 어노테이션을 출력.
2.해당 메소드의 어노테이션 정보를 새 어노테이션 인터페이스 변수에 담고
그 변수에서 어노테이션 값이 사용자가 지정한 값을 가지고 있다면 해당메소드 출력.
- package com.journaldev.annotations;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Method;
- public class AnnotationParsing {
- public static void main(String[] args) {
- try {
- for(Method method : AnnotationParsing.class.getClassLoader()
- .loadClass(("com.journaldev.annotations.AnnotationExample"))
- .getMethods()) {
- if(method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
- try {
- //iterates all the annotations available in the method
- for(Annotation anno : method.getDeclaredAnnotations()) {
- System.out.println("Annotation in Method" +method+ " : " +anno);
- }
- MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
- if(methodAnno.revision()==1) {
- System.out.println("Method with revision no 1 = " +method);
- }
- } catch (Throwable ex) {
- ex.printStackTrace();
- }
- }
- }
- } catch (SecurityException | ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
Reference
http://tutorials.jenkov.com/java-reflection/annotations.html
http://tutorials.jenkov.com/java/annotations.html
http://www.javacodegeeks.com/2014/11/java-annotations-tutorial.html
http://hmkcode.com/spring-configuration-xml-annotation-java/
'Java' 카테고리의 다른 글
| 직렬화(serialization) 에 대한 짧은 이야기 (Q/A) (0) | 2015.07.07 |
|---|---|
| 자바 어노테이션의 모든것 - (4) (0) | 2015.07.05 |
| 자바 어노테이션의 모든것 - (2) (0) | 2015.07.04 |
| 자바 어노테이션의 모든것 - (1) (2) | 2015.07.04 |
| 자바언어에서 동기화의 어려움 (1) (0) | 2015.05.20 |