본문 바로가기
일하다가??

자바 어노테이션 (Java Annotation)

by 램쥐뱅 2016. 4. 30.

서로다른시스템 간의 바이트 배열의 스트림 정보로 정보를 교환하는 작업인 전문통신을 개발하게 되었을 때였다.


바이트 스트림을 어떻게 하면 잘 정제해서 예쁘게 객체에 담을 수 있을까 고민하던 찰나. 어노테이션을 보게되었다.


Annotation.


자바5부터 등장한 어노테이션된 요소들의 행동으로부터 프로그램의 행위를 추출하여, 

필요시 컴파일러나 VM이상호 의존적인 코드를 생성하는, 프로그램 요소와 메타 태그에 관계된 매커니즘.


@Override, @SuppressWarnings("unused") 같은 것을 많이 보아왔고, Spring Framework 에서 Annotation을 편하다 신기하네 하고 지원이 되는 것을 찾아 사용하기만 했지 직접 만들어서 사용할일은 없었다.


정보가 쭉 담겨져 오는 바이트 스트림같은 경우 시스템간에 약속된 길이만큼 잘라서 사용하고 또 그 데이터가 어떤 특징이 있는가 같은 메타정보들을 확일할 필요가 있었고 각각 객체의 필드들이 메타정보를 가지고 있을 필요성이 있었는데 아래와같이


 @Retention(RetentionPolicy.RUNTIME)

 @Target(ElementType.FIELD) 

 public @interface OffsetInfo {

        public enum DataType{

            STRING, NUMERIC, ARRAY

        }

        int length() default 0;

        DataType dataType();

        string name() default "";

 }


@IfInfo(id=DataId.IF000001, name="사과")

 class Apple {

        @OffsetInfo(length=5, dataType=Type.NUMERIC, name="수량")

        private String amount;

        @OffsetInfo(length=10, dataType=Type.STRING, name="색")

        private String color;

        ...

        @Override

        public String toString(){

                Field[] fields = getClass().getFields();

                for (Field field : fields){

                        OffsetInfo offsetInfo = field.getAnnotation(OffsetInfo.class);


                        //리플랙션 기능이용 출력되게끔

                        System.out.println(field.getName()+"["+offsetInfo.getName()+"] : "+field.get(this);) 

                }

        }

 }


만들어서 사용을하니 비지니스 로직과는 별도로 주가적인 사항들을 명확하고 누가봐도 알아보기 쉽게 표현해줄수가 있었다.

(기존에는 하나의 fianl static 형식의 정보가 담긴 인터페이스 또는 클래스, XML 같은 다른 정보들을 관리해주는 다른 특정 인스턴스를 만들어서 이용했음..)


어노테이션을 이용해서 클래스를 만들어준후, 파싱을 담당해주는 유틸형식의 클래스를 만들어 Java 리플렉션 기능을 활용하니

너무너무 효율적으로 사용할수 있게 되었다. !!

클래스만 봐도 이게 어떤정보인지 알수있는게 가장큰 장점이고 Java 리플렉션 기능을 활용해 Annotation의 정보들을 모두 활용 할수 있다는 것 또한 큰 장점으로 활용되어 디버깅이 손쉬워지고 오류 확률도 낮아졌다.


아래는 개발하는 동안 참조했던 내용들이다.


= .java부터 .class까지
 .java => Parser => Type checker => [Annotation Checker] => Class File writer => .class

= 어노테이션 규칙
 * @interface + 어노테이션 이름
 * 어노테이션 소스코드 내부의 메소드 선언은 매개변수를 지닐 수 없다.
 * 어노테이션 소스코드 내부의 메소드 선언은 clauses를 throw 할 수 없다.
 * 메소드의 반환 타입은 primitives, String, Class, enum과 primitives배열, String배열, Class배열, enum배열 중 하나이다.

= 분류
 * marker ; @AnnotationTypeName
 * single-element ; @AnnotationTypeName(single-element)
 * normal, full-value, multi-value ; @AnnotationName(element=value, element=value, ...)

= 내장 어노테이션
== java.lang.annotation
@Retention
 - Retention은 어노테이션이 얼마나 오랫동안 유지되는지에 대해, JVM이 어떻게 사용자 어노테이션을 다루어야 하는지를 서술합니다.
 * SOURCE - 어노테이션이 컴파일 타임시 버려진다는 것을 의미합니다. retention정책이 source로 정의되어 있으면, 클래스 파일은 어노테이션을 지니지 못합니다.
 * CLASS - 어노테이션이 생성된 클래스 파일에서 나타날 것이라는 것을 의미합니다. 그러나 런타임시에는 이 어노테이션을 이용하지 못합니다.
 * RUNTIME- 이는 런타임시 JVM에서 어노테이션의 이용이 가능하다는 것을 의미합니다. 이러한 어노테이션을 읽는 사용자 로직을 가짐으로써 런타임시 무언가를 할 수 있습니다.

@Target
 - Target은 어디에 어노테이션을 넣을 수 있는지를 서술합니다. field, method, class가 정의된 곳에 어노테이션을 넣을 수 있습니다.
 * TYPE - class, interface, enumeration에 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * METHOD - method 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * PARAMETER - parameter 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * PACKAGE - package 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * FIELD - field 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * LOCAL_VARIABLE - 지역 변수 선언에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * CONSTRUCTOR - 생성자에만 어노테이션을 적용할 수 있다는 것을 의미합니다.
 * ANNOTATION_TYPE - 어노테이션 타입에만 어노테이션을 적용할 수 있다는 것을 의미합니다.



참조.


Annotation A부터 n까지 : http://netpyoung.tistory.com/m/post/100 

Java Annotation: 인터페이스 강요로부터 자유를… : http://www.nextree.co.kr/p5864/

[JAVA] 어노테이션(Annotation) : http://hiddenviewer.tistory.com/88

'일하다가??' 카테고리의 다른 글

OSX : NFS Mount (NFS 마운트)  (0) 2016.10.31
해시값의 복호화 ??  (18) 2016.10.08
암호화 알고리즘 종류  (1) 2016.10.08
Servlet 이란? 서블릿 이란?  (4) 2016.05.12
java volatile 키워드  (7) 2016.04.30

댓글