검수요청.png검수요청.png

어노테이션

위키원
이동: 둘러보기, 검색

어노테이션(annotation)은 자바 소스코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여서 사용한다. JDK 1.5 버전 이상에서 사용 가능하다. 영어 발음에 가깝게 애너테이션([æ̀nətéiʃən])이라고도 한다. 자바 어노테이션은 클래스 파일에 임베디드되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.[1]

개요[편집]

어노테이션이란 java 5부터 등장한 기능이며 @를 이용한 주석, 자바코드에 주석을 달아 특별한 의미를 부여한 것이다.

또한 컴퍼일러가 특정 오류를 억제하도록 지시하는 것과 같이 프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공, 코드에 정보를 추가하는 정형화된 방법이다.[2]

어노테이션이 붙은 코드는 어노테이션의 구현된 정보에 따라 연결되는 방향이 결정된다. 따라서 전체 소스코드에서 비즈니스 로직에는 영향을 주지는 않지만 해당 타겟의 연결 방법이나 소스코드의 구조를 변경할 수 있다.

쉽게 말해서 "이 속성을 어떤 용도로 사용할까, 이 클래스에게 어떤 역할을 줄까?"를 결정해서 붙여준다고 볼 수 있다.
어노테이션은 소스코드에 메타데이터를 삽입하는 것이기 때문에 잘 이용하면 구독성 뿐 아니라 체계적인 소스코드를 구성하는데 도움을 준다.

// 어노테이션 사용의 예
@CanSale
public class Apple{
    ...
}

어노테이션(annotation)은 위의 예시와 같이 @(;AT)을 앞에 붙여서 표현한다. 이 어노테이션은 자바가 기본적으로 제공하기도 하고(@Deprecated, @Override, @SuppressWarning), 개발자가 직접 정의해서 사용할 수 있다. 개발자는 어노테이션을 붙일 타겟과 유지시기 등을 설정하여 자신이 원하는 용도로 활용 가능하다. 이 기능을 잘 활용한다면, 비즈니스 로직과는 별도로 시스템 설정과 관련된 부가적인 사항들은 @에게 위임하고 개발자는 비즈니스 로직 구현에 집중할 수 있다. 따라서 어노테이션을 통해 우리는 AOP(Aspect Oriented Programming; 관심지향프로그래밍)을 편리하게 구성할 수 있다. 어노테이션은 컴파일시기에 처리될 수도 있고 자바의 리플렉션을 거쳐서 런타임에 처리될 수도 있다. 리플렉션은 실행 중인 자바 클래스의 정보를 볼 수 있게 하고, 그 클래스의 구성 정보로 기능을 수행할 수 있도록 한다. 따라서 자바는 리플렉션 기능이 있기 때문에 어노테이션을 더욱 효율적으로 사용할 수 있다.[3]

특징[편집]

어노테이션 실행절차[편집]

Annotation.PNG 어노테이션은 소스코드에 붙이는 하나의 라벨이라고 생각하면 이해가 쉽다. 위 그림은 커스텀 어노테이션의 사용과 실행 절차를 사과가 포장되는 과정에 비유하여 설명하고 있다. 판매가능한 사과에는 판매가능(@CanSale)라벨지를 달아서 포장과정시 이를 판별하여 제품을 포장한다고 가정해 본다면. 먼저, 타겟에 적합한 라벨지를 만들어야 한다. 라벨에는 이 라벨을 붙일 대상을 명시하고, 라벨은 언제까지만 타겟에 부착할 것인지 등을 적는다. 그리고 라벨에 이름을 적으면 라벨이 만들어진다. 사과의 상태에 따라 판매가능 라벨을 부착한다. 즉, 싱싱한 사과라는 타겟에 판매가능이라는 어노테이션을 부착한 것이다. 그럼 제품포장 과정에서는 이 라벨을 보고 판별하여 제품을 포장할 것이다. 이렇게 제품 포장 기능이 실행되어진다.

이와같이 어노테이션을 직접 정의해서 사용하기 위해서는 먼저 어노테이션을 정의한 후, 원하는 타겟에 적용한다. 그 후 어노테이션이 붙은 타겟을 어떻게 사용할 지 기능을 구현하면, 해당 기능이 실행될 때 타겟에 붙은 어노테이션에 따라서 타겟의 경로가 결정될 것이다.

효율적인 어노테이션 사용의 예[편집]

  1. 도메인 객체마다 그에 맞는 방법으로 저장 : 가장 원초적인 방법은 서로 다른 도메인 객체에 맞는 처리 방법을 지정해 주는 것이다. 하지만 이 방법은 도메인 객체가 늘어날 때마다 데이터 관리 방법을 추가 지정해줘야하는 번거로움이 있다. 또한 Data-Server에서 Service-Server의 도메인 객체의 속성을 알고있어야 한다는 점에서 좋지 않은 설계이다.
  2. 특정 인터페이스를 상속한 도메인 객체들을 일관된 방법으로 저장 : Service-Server에 있는 모든 도메인 객체가 데이터관리를 위한 틀로서 작용할 수 있는 특정 인터페이스를 상속받도록 하는 것이다. 이렇게 되면 Data-Server에서는 일관된 도메인객체의 속성을 사용하기 때문에 도메인 객체가 여러 개이더라도 데이터 서버 구현은 한 번만 정의해서 데이터를 관리할 수 있다.
  3. @Annotation을 이용해서 저장 : 서로 다른 도메인 객체이더라도 같은 어노테이션이 붙어있으면 똑같은 경로로 나가도록 구현할 수 있기 때문에 인터페이스를 상속받지 않더라도 통합된 방법으로 데이터관리를 할 수 있다.[3]

용도[편집]

  • @Override 어노테이션처럼 컴파일러를 위한 정보를 제공하기 위한 용도
  • 스프링 프레임워크의 @Controller 어노테이션처럼 런타임에 리플렉션을 이용해서 특수 기능을 추가하기 위한 용도
  • 컴파일 과정에 어노테이션 정보로부터 코드를 생성하기 위한 용도

어노테이션[편집]

내장 어노테이션[편집]

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

  • @Override

해당 메소드가 부모 클래스에 있는 메소드를 재정의했다는 것을 명시적으로 선언한다.

  • @Deprecated

더 이상 사용되지 않는 클래스나 메소드 앞에 추가한다.

  • @SuppressWarnings

프로그램에는 문제가 없는데 간혹 컴파일러가 경고를 뿜을때가 있다.
이를 무시하라고 프로그래머에게 알려준다.

  • @safeVarargs

제너릭같은 가변인자 매개변수를 사용할 때 무시한다.(java 7 이상)

  • @FunctionalInterface

람다 함수 등을 위한 인터페이스를 지정한다.
메소드가 없거나 두개 이상이 되면 컴파일 오류가 난다.(java 8 이상)

메타 어노테이션[편집]

Meata Annotation을 활용해 Custom Annotation을 만들 수 있다.

  • @Retention

어떤 시점까지 어노테이션이 영향을 미치는지 결정한다.

  • @Documented

해당 어노테이션 정보가 JavaDocs(API) 문서에 포함한다.

  • @Target

어노테이션이 적용할 위치를 결정한다.

  • @Inherited

모든 자식 클래스가 부모 클래스의 어노테이션을 사용할 수 있다는 것을 선언한다.

  • @Repeatable

반복적으로 어노테이션을 선언할 수 있다.

java 7부터 추가 어노테이션이 언어에 추가되었다.[1]

  • @SafeVarargs
  • @FunctionalInterface
  • @Repeatable

예제[편집]

정수 값 주입 예제[편집]

1. Annotation 인터페이스 작성

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InsertIntData {
    int data() default 0;
}

인터페이스를 만들어주는데 앞에 @ 표시를 붙이고 맴버 변수에 data라는 주입을 받을 값을 만들어 준다.

2. Annotation을 사용할 예제 클래스 작성

public class AnnotationExam01 {
    @InsertIntData(data = 30)
    private int myAge;

    @InsertIntData
    private int defaultAge; 

    public AnnotationExam01() {
        this.myAge = -1;
        this.defaultAge = -1;
    }

    public int getMyAge() {
        return myAge;
    }

    public int getDefaultAge() {
        return defaultAge;
    }
}

변수는 다음과 같이 myAge와 defaultAge 두 가지인데 myAge에 Annotation에서는 30으로 값을 주입한다.
하지만 defaultAge에서는 값이 없는데 이 경우 Annotation에서 정한 기본 값인 0으로 값이 주입된다.
생성자의 경우 값이 없을 경우 -1을 기본으로 저장한다.

문자열 값 주입 예제[편집]

1. Annotation 인터페이스 작성

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InsertStringData {
    String data() default "default";
}

정수 값 주입 예제와 비슷하다.
기본 값으로는 default 문자열을 가집니다.

2. Annotation을 사용할 예제 클래스 작성

public class AnnotationExam02 {
    @InsertStringData(data = "MHLab")
    private String myData;

    @InsertStringData
    private String defaultData;

    public AnnotationExam02() {
        myData = "No data";
        defaultData = "No data";
    }

    public String getMyData() {
        return myData;
    }
 
    public String getDefaultData() {
        return defaultData;
    }
}

변수는 다음과 같이 myData와 defaultData 두 가지인데 myData에 Annotation에서는 "MHLab"으로 값을 주입힌다. 하지만 defaultData에서는 값이 없는데 이 경우 Annotation에서 정한 기본 값인 "default"로 값이 주입된다. 생성자의 경우 값이 없을 경우 "No data" 문자열을 기본으로 저장한다.[4]

각주[편집]

  1. 1.0 1.1 <자바 애너테이션>, <<위키백과>>
  2. <어노테이션(Annotation)>,<<빨간색 코딩>>, 2016-12-24
  3. 3.0 3.1 <Java Annotation>, <<NEXTREE>>, 2014-07
  4. <Java에서 커스텀 어노테이션(Annotation) 만들고 사용하기>, <<MHLab Blog>>, 2017-12-14

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 어노테이션 문서는 프로그래밍에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.