Annotation

유동현·2022년 12월 1일
0

스프링MVC

목록 보기
12/13
post-thumbnail

개요

  • 일종의 주석으로 데이터를 부연설명하는 데이터 즉, 메타데이터이다.

  • .java(소스 레벨) → [컴파일러(Compiler)] → .class → [JVM : Runtime]
    → 우리가 작성한 소스코드 바로 자바가 읽는게 아니라, 한 번 과정을 거치고 읽음
    우리가 컴파일러한테 건네준 .java 가 실행되는게 아니라,
    컴파일러가 번역해서 결과로 남겨둔 .class 가 실행되는 것이다.
    이때 컴파일러가 컨테이너 역할을 수행한다.

  • 이 과정에서 보통 컴파일이 되면 주석이 제거
    (//, /.../, /*.../)

  • 이때 주석을 다른 기본 문법을 해치지 않고 컴파일러 or JVM에게 전달하는 방법이 Annotation 『@』 : Annotation, JDK 1.5(JavaSE 5.0)부터 사용 가능, Runtime 까지도 존재



쓰는 이유

1.문서화

  • 메타 데이터는 메소드가 다른 메소드에 의존하고 있다는 것을 알려주는 유용한 방법으로 또한, 그들이 불완전한지, 특정 클래스가 또 다른 클래스를 래퍼런싱 하는지
    등을 알려준다.

  • 유용하긴 하지만 문서화는 메타 데이터를 자바에 추가하는 것과 가장 관련이 적은 항목.

  • 코드 문서화에 있어서는 Javadoc 라는 사용이 쉽고 강력한 방식을 제공하고 있기 때문이다. → api document 같은 문서 만들어줌 (엄청 편하고 강력함)

    2.컴파일러 체크

  • 메타 데이터의 장점은 컴파일러가 메타 데이터를 사용하여 몇 가지 기본적인 컴파일 시간 체크를 수행할 수 있는 기능

  • 예를 들어 Override 어노테이션을 이용하여 슈퍼 클래스의 메소드가 재정의된 것을 기술, 자바 컴파일러는 메타 데이터에서 알려주는 작동이 실제로 코드 레벨에서 발생한다는 것을 확인할 수 있다.

  • 이는 실수로 오버라이딩하는 경우의 버그를 쉽게 찾을 수 있다.
    → 런타임이 아니라 컴파일과정에서 인지하도록 함

3.코드 분석

  • 좋은 어노테이션 또는 메타 데이터 툴의 최고의 기능은
    여분의 데이터를 사용하여 코드를 분석하는 것이다.
    간단한 경우, 코드 목록을 구현하고 필요한 인풋 유형을 제공하고
    리턴 유형을 제시한다. → 자바의 리플렉션과 비슷한 기능

  • 많은 경우 메소드는 인풋으로 변수를 받아들이고 아웃풋으로 리턴한다.
    이는 메소드가 원하는 것이 아니다.
    예를 들어, 매개변수 유형이 Object 이지만 메소드는 Integer 를
    사용해서만 작동한다. 이는 메소드가 겹쳐쓰기된 곳에서 쉽게 발생할 수 있다.
    그리고 슈퍼 클래스가 메소드를 일반 매개변수로 선언하던가
    많은 직렬화가 진행되는 시스템에서도 쉽게 발생한다.
    두 경우 모두 메타 데이터는 코드 분석 툴을 지정하여 매개변수 유형이 Object 이더라도 정말로 원하는 것을 Integer 라는 것을 나타낼 수 있다.
    이러한 종류의 분석은 상당히 유용하며 그 가치가 높다고 한다.


  • 보다 복잡한 경우 코드 분석 툴은 모든 종류의 추가 테스크들을 수행할 수 있다.
    그 예 중 하나가 Enterprise JavaBean(EJB) 컴포넌트

  • 심지어 간단한 EJB 시스템도 의존성과 복잡성은 상당하다.
    로컬 인터페이스이면서 로컬 홈 인터페이스가 될 가능성과 함께
    홈 인터페이스와 원격 인터페이스를 얻는다.
    이 모든 클래스들을 연동시키는 것은 많이 힘들다.

  • 하지만 메타 데이터는 이 문제에 대한 솔루션을 제공한다.
    좋은 툴은 이 모든 의존성을 관리하면서 코드-레벨 연결이 없지만
    코드-레벨 관계를 가진 클래스들이 연동될 수 있도록 한다.
    이것이 바로 메타 데이터의 진정한 가치라고 할 수 있다.

Annotation의 종류

Mark Annotation

  • 변수가 없다. 이 어노테이션은 이름으로 구분되며 추가 데이터 없이 나타난다.
    예를 들어, @MarkerAnnotation 은 marker 어노테이션이다.
    데이터가 없으며 단지 어노테이션 이름만 있을 뿐이다.
    ex) @Stateless
    @Override

Single-value Annotation

→ 무언가를 설정하면서 어노테이션 설정

  • marker 와 비슷하지만 데이터를 제공한다.
    싱글 비트 데이터를 제공하기 때문에 간단한 신택스를 사용할 수 있다.
    (단, 어노테이션 유형이 이 문법을 수용해야 함)
    : @SingleValueAnnotation("my data")
    → 이는 @ 표시만 제외하고는 일반적인 자바 메소드 호출과 비슷하다.

Full Annotation(Multi value Annotation)

  • 다중 데이터 멤버를 갖고 있다.
    결과적으로 전체 신택스를 사용해야 한다.
    (그리고, 어노테이션은 일반 자바 메소드와 더 이상 비슷하지 않다.)
    : @FullAnnotation(var1="data value1", var2="data value2", var3="data value3")
    → 해당 값이 어떤 파라미터에 대입되는 걸 명시하는 구조

Custom Annotation 구현

  • 개발자가 직접 Annotation 을 구현
    → 지금 볼 필요는 없음. 실무에서 만들어서 쓸 일 없음
    ex)
    public @interface TODO // Single-value Annotation
    {
    String value(); // value 가 아닌 이름을 사용하면
    } // 사용 시 메소드의 이름을 써준다.
 // @TODO("something todo")

      public @interface TODO		// Single-value Annotation
      {
          String msg();			// value 가 아닌 이름을 사용한 경우
      }

      // @TODO(msg="Something todo")




Annotation 을 구분하는 또 다른 기준

  • 1) Simple Annotation
    메소드나 변수 위에 붙이는 일반적인 Annotation
    ex) @Override

  • 2) Meta Annotation (Complex Annotation)
    Annotation 의 Annotation
    (한 Annotation 위에 다른 Annotation 설정)

※ Meta Annotation : 사용 빈도 ↓

  • 1) @Target Annotation
    작성한 Annotation 이 어디에서 사용하게 될 지를 결정(→ 대상 지정)

    @Target(
    {
    ElementType.type // 클래스, 인터페이스, enum
    , ElementType.METHOD // 생성자를 제외한 모든 메소드
    , ElementType.CONSTRUCTOR // 생성자
    , ElementType.ANNOTATION_TYPE // 메타 Annotation
    })

  • 2) @Retention Annotation
    @Retention Annotation([속성값])
    작성한 Annotation의 지속성을 설정

    • RetentionPosicy.SOURCE
      : 컴파일러가 컴파일 시 삭제하여 클래스 파일에 저장되지 않는다.
    • RetentionPosicy.CLASS
      : 클래스 파일에 저장되지만 JVM 은 무시
    • RetentionPosicy.RUNTIME
      : 클래스 파일에 저장되고 JVM 은 유지




내장(Built-in) Annotation

  • java.lang.* 에 정의된 3개의 표준 어노테이션

  • 1) Override

  • 2) @Deprecated
    @Override 와 마찬가지로 @Deprecated 는 marker 어노테이션이다.
    @Deprecated 를 사용하여 더 이상 사용되지 말아야 할 메소드에 주석을 부여한다.
    @Override 와 다른 점은, @Deprecated 는 더 이상 사용되지 말아야 하는
    (deprecated) 메소드와 동일한 라인상에 놓여져야 한다.

+) 이클립스에 초록색 동그라미 → 메소드
초록색 동그라미 + A → 추상적인 메소드
초록색 동그라미에 / 그어져 있는 거 → Deprecated

public class DeprecatedClass
      {
	   @Deprecated public void deSomething()
	   {
	       // ... 실행 코드
	   }  

	   public void doSomethingElse()
	   {
	       // ... 실행 코드
	       // doSomething() 메소드를 사용하는 것 보다
	       // 향상된 형태의 코드	   
	   }
      }	    
  • 3) @SuppressWarnings
    번거로운 경고를 제거한다.
    Override 나 Deprecated 와는 다르게 @SuppressWarnings 는 변수를 갖고 있다.
    따라서 이를 작동하게 하려면 Single-value 어노테이션 유형으로 사용해야 한다.
    값 어레이로서 변수를 제공할 수 있다.
    각각 삭제할(Suppress) 특정 유형의 경고를 나타낸다.
    → sc.close(); 노란색 뜨는거 그런거 안뜨게 할 수 있음!
     @SuppressWarnings(value="unchecked")
      public void nonGenericMethod()
      {
	   List wordList = new ArrayList();
	   wordList.add("foo"); 
      }

0개의 댓글