Java

자바 어노테이션의 모든것 - (3)

[하마] 이승현 (wowlsh93@gmail.com) 2015. 7. 4. 13:19


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 : 어노테이션된 타입이 얼마나 지속되는가를 지칭


[메소드에 지정할 어노테이션 정보들을 정의해놓은 인터페이스] 

  1. package com.journaldev.annotations;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Inherited;  
  6. import java.lang.annotation.Retention;  
  7. import java.lang.annotation.RetentionPolicy;  
  8. import java.lang.annotation.Target;  
  9.   
  10.   
  11. @Documented  
  12. @Target(ElementType.METHOD)  
  13. @Inherited  
  14. @Retention(RetentionPolicy.RUNTIME)  
  15. public @interface MethodInfo {  
  16.  String author() default "Pankaj";  
  17.  String date();  
  18.  int revision() default 1;  
  19.  String comments();  
  20. }  


[어노테이션을 적용한 메소드들이 정의되어 있는 클래스 예] 

  1. package com.journaldev.annotations;  
  2.   
  3. import java.io.FileNotFoundException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. public class AnnotationExample {  
  8.  public static void main(String[] arg) {  
  9.  }  
  10.  @Override  
  11.  @MethodInfo(comments = "deprecated method",  
  12.     date = "Nov 17 2012",  
  13.     revision=1)  
  14.  public String toString() {  
  15.   return "Overriden toString method";  
  16.  }  
  17.    
  18.  @Deprecated  
  19.  @MethodInfo(comments = "deprecated method",  
  20.     date = "Nov 17 2012")  
  21.  public static void oldMethod() {  
  22.   System.out.println("old method, don't use it.");  
  23.  }  
  24.    
  25.  @SuppressWarnings({"unchecked""deprecation"})  
  26.  @MethodInfo(author = "Pankaj",  
  27.     comments = "Main method",  
  28.     date = "Nov 17 2012",  
  29.     revision = 10)  
  30.  public static void genericsTest() throws FileNotFoundException {  
  31.   List list = new ArrayList();  
  32.   list.add("abc");  
  33.   oldMethod();  
  34.  }  
  35. }  


[Reflection을 사용하여 어노테이션 정보를 분석하는 클래스 :

테스트 클래스로 클래스의 모든 메소드를 로드하고, 그 메소드 중에 어노테이션 인터페이스

에 정의된 어노테이션을 마킹한 각 메소드에 한해서만 이하 작업을 수행.]

1.해당 메소드의 모든 어노테이션을 출력.

2.해당 메소드의 어노테이션 정보를 새 어노테이션 인터페이스 변수에 담고

그 변수에서 어노테이션 값이 사용자가 지정한 값을 가지고 있다면 해당메소드 출력.

  1. package com.journaldev.annotations;  
  2.   
  3. import java.lang.annotation.Annotation;  
  4. import java.lang.reflect.Method;  
  5.   
  6. public class AnnotationParsing {  
  7.  public static void main(String[] args) {  

  8.   try {  
  9.    for(Method method :    AnnotationParsing.class.getClassLoader()  
  10.                                          .loadClass(("com.journaldev.annotations.AnnotationExample"))  
  11.                                          .getMethods()) {  

  12.      if(method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {  
  13.       try {  
  14.        //iterates all the annotations available in the method  
  15.        for(Annotation anno : method.getDeclaredAnnotations()) {  
  16.         System.out.println("Annotation in Method" +method+ " : " +anno);  
  17.        }  
  18.        MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);  
  19.        if(methodAnno.revision()==1) {  
  20.         System.out.println("Method with revision no 1 = " +method);  
  21.        }  
  22.          
  23.       } catch (Throwable ex) {  
  24.        ex.printStackTrace();  
  25.       }  
  26.      }  
  27.    }  
  28.   } catch (SecurityException | ClassNotFoundException e) {  
  29.    e.printStackTrace();  
  30.   }  
  31.  }  
  32. }  





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/