본문으로 바로가기

자바 커스텀 어노테이션 만들기

category JAVA 2020. 8. 2. 12:22

어노테이션

  • 소스 코드에 메타 데이터를 표현하는 것입니다.
  • 컴파일 과정, 런타임 과정에서 코드를 어떻게 처리해야할지 명시하는 것입니다.

자바에서 기본적으로 제공하는 어노테이션

  1. @override 메소드가 오버라이드 됬는지 검증합니다. 만약 부모클래스 또는 인터페이스에서 해당 메서드를 찾을 수 없다면 컴파일 오류가 발생합니다.
  2. @Deprecated 메소드를 사용하지 말도록 유도합니다.
  3. @SupperessWarnings 컴파일 경고를 무시하도록 합니다.
    이 외에도 여러가지 있습니다.

Meta Annotations

  • 이 메타 어노테이션을 이용하여 사용자 커스텀 어노테이션을 만들어 낼 수 있습니다.
  1. @Retention 어노테이션의 범위, 어떤 시점까지 어노테이션이 영향을 미치는지 결정합니다.
  2. @Documented 문서에도 어노테이션 정보가 표현됩니다.
  3. @Target 어노테이션이 적용될 위치를 결정 합니다. 적용 대상에는 method, fleid, type(class), 생성자, parameter 등이 있습니다.
  4. @Inherited 이 어노테이션을 선언하면 부모클래스에서 어노테이션을 상속 받을 수 있습니다.

어노테이션 생성하기

  • 자바에서 어노테이션을 생성하는법은 간단합니다.

    public @interface MyAnno {
    }
  • 이후에 몇 메타 어노테이션을 선언해줍니다.

    @Target(ElementType.METHOD)                        // 적용대상은 method입니다.
    @Retention(RetentionPolicy.RUNTIME)                // 유지정책은 runtime입니다. 컴파일 이후에도 JVM이 참조합니다.
    public @interface MyAnno {
    // String 타입으로 사용 가능합니다.
      public String value();
    }

어노테이션 적용하기

  • 생성해준 어노테이션을 적용할 클래스입니다.
public class Target {

    @MyAnno(value = "연습입니다.")
    public void sub() {
        System.out.println("Target");
    }

}

실제 어노테이션을 찾는 컨테이너 클래스

  • 자바 리플렉션을 이용하여 프로그램 실행 시 커스텀 어노테이션을 사용한 곳과 값들을 얻어옵니다.
public class MainClass {
    public static void main(String[] args) throws Exception {


        // 특정 메서드의 어노테이션을 가져올 수 있습니다.
        Method method = Target.class.getMethod("sub");
        Annotation[] annotations = method.getDeclaredAnnotations();

        for (Annotation anno : annotations) {
            MyAnno myAnno = (MyAnno) anno;
            System.out.println(myAnno.value());
        }

        // 동적 클래스 생성으로 객체를 얻어온 다음
        // 여러 메서드들의 어노테이션 value()를 얻어옵니다.
        String className = "com.java.anno01.Target";
        Class<?> cls = Class.forName(className);
        Target a = (Target) cls.getDeclaredConstructor().newInstance();
        a.sub();

        Method[] methods = cls.getDeclaredMethods();

        for (int i=0; i<methods.length; i++) {
            if (methods[i].isAnnotationPresent(MyAnno.class)) {
                MyAnno myAnno = methods[i].getAnnotation(MyAnno.class);
                System.out.println(myAnno.value());
            }
        }
    }
}