Java

[Team Study] [Annotation] 자바 어노테이션에 대해 알아보자

고인돌개발자 2021. 5. 12. 18:20

학습목표 : 자바 어노테이션을 이해하고 그 종류에 대해 공부한다.


사전적 의미
annotation : 주석(을 달다)   | 
an + notation : 하나의 표기법


※ Java Tutorials : https://docs.oracle.com/javase/tutorial/java/annotations/index.html

 

Annotations, a form of metadata, provide data about a program that is not part of the program itself.
Annotations have no direct effect on the operation of the code they annotate.

Annotations have a number of uses, among them:

  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — Some annotations are available to be examined at runtime.

From . 위키피디아

 

자바 애너테이션(Java Annotation)은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여서 사용한다. JDK 1.5 버전 이상에서 사용 가능하다. 자바 애너테이션은 클래스 파일 임베디드되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.


1. 어노테이션의 용도(역할)

    - 컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
    - 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공
    - 실행 시 특적 기능 (소스, 컴파일, 런타임)을 실행하도록 정보를 제공한다.


2. 어노테이션 종류

    a) 표준(내장) 어노테이션( built-in annotaion )  - 자바가 기본적으로 제공하는 어노테이션

@Override 컴파일러에게 오버라이딩하는 메서드라는 것을 알린다.
@Deprecated 앞으로 사용하지 않을 것을 권장하는 대상에 붙인다.
@SuppressWarnings 컴파일러의 특정 경고메시지가 나타나지 않게 해준다.
@SafeVarargs 자바 7부터 추가되었으며, 생성자나 메소드의 가변인자 파라미터가 안전하게 사용된다는 것을 나타내기 위해 사용합니다. (String… values와 같은 형태를 가변인자라고 함)
@FunctionalInterface 자바 8부터 추가되었으며, 인터페이스를 함수형 프로그래밍인 람다 방식으로 사용하기를 추천하는 용도로 사용합니다. (자바 8부터 추가)
@Native native메서드에서 참조되는 상수 앞에 붙인다.(JDK1.8)

   

b) 메타 어노테이션 ( Meta annotation ) - 어노테이션을 위한 메타 정보를 포함. 어노테이션의 속성으로 이해할 수 있다.

@Target 어노테이션이 적용가능한 대상을 지정하는데 사용한다.
  • ElementType Enum에 선언된 값
  • TYPE : class, interface, enum에 적용된다. 
  • FIELD : 클래스 필드 변수
  • METHOD : 메서드
  • PARAMETER : 메서드 인자
  • CONSTRUCTOR : 생성자
  • LOCAL_VARIABLE : 로컬 변수
  • ANNOTATION_TYPE : 어노테이션 타입에만 적용된다
  • PACKAGE : 패키지 
  • TYPE_PARAMETER : 자바8부터 추가된 값으로 제네릭 타입 변수에 적용된다. (ex. MyClass<T>)
  • TYPE_USE : 자바8부터 추가된 값으로 어떤 타입에도 적용된다 (ex. extends, implements, 객체 생성시등등)
@Documented 어노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다.
@Inherited 어노테이션이 자손 클래스에 상속되도록 한다.
@Retention 어노테이션이 유지되는 범위를 지정하는데 사용한다. (SOURCE, CLASS, RUNTIME)
  • RetentionPolicy Enum에 선언된 값 
  • SOURCE : 자바 컴파일에 의해서 어노테이션은 삭제된다
  • CLASS : 어노테이션은 .class 파일에 남아 있지만, runtime에는 제공되지 않는 어노테이션으로 Retention policy의 기본 값이다
  • RUNTIME : runtime에도 어노테이션이 제공되어 자바 reflection으로 선언한 어노테이션에 접근할 수 있다
@Repeatable 어노테이션을 반복해서 적용할 수 있게 한다.(JDK1.8)

 

c) 커스텀 어노테이션 ( Custom Annotation ) - 사용자가 직접 만들어 사용할 수 있다. ( @interface 로 선언되어진다. )
    - 아래 예제 

 


3. 커스텀 어노테이션 실습

      a) @Retention(RetentionPolicy.SOURCE)

package team.study._annotaion;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * this program is for Fish
 * @author dhkim 
 */

@Documented
//@Target(ElementType.TYPE) // Target 을 설정하지 않으면, All  
@Retention(RetentionPolicy.SOURCE) // SOURCE, CLASS, RUNTIME
public @interface AnnoFish{			
}

  b) @Retention(RetentionPolicy.RUNTIME)

package team.study._annotaion;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * this program is for Bird
 * @author dhkim 
 */
@Documented
@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface AnnoBird {
	
	/* annotation elements 
	 * value() is default 
	 * */
	String name() default "";
	
}

 

c. Main()

package team.study._annotaion;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class MainAnnotation {
	
	public static void main(String[] args) throws Exception, SecurityException {
			
		System.out.println("--------- MainAnnotation ---------");
		
		Eagle ms = new Eagle();
		
		String strCompany="";
		
		/*		
		Method method = Eagle.class.getMethod("doFunc"); //자바 리플렉션 getMethod로 메서드 doFunc를 얻어온다
		Annotation[] annotations = method.getDeclaredAnnotations(); //메서드에 선언된 어노테이션 객체를 얻어온다
		        for (Annotation annotation : annotations) {
		            if (annotation instanceof AnnoBird) {
		            	AnnoBird annoBird = (AnnoBird) annotation;
		                System.out.println("name: " + annoBird.name()); //어노테이션에 지정한 값을 프린트한다
		            }
		        }		       
		*/
		
        Annotation annotation = Eagle.class.getMethod("doFunc") 
                            .getAnnotation(AnnoBird.class); //메서드 doFunc에 선언된 AnnoBird의 어노테이션 객체를 얻어온다

        if (annotation instanceof AnnoBird) {
        	AnnoBird myAnnotation = (AnnoBird) annotation;
            //System.out.println("name: " + myAnnotation.name());
        	strCompany = myAnnotation.name();
        }
		
        System.out.printf("\nThe annotation name is %s \n\n",strCompany);
        
		/* Bird ? or  */
		if("SPARROW,EAGLE,DOVE,SEAGULL".indexOf(strCompany) >= 0) {
			System.out.printf("Annotation Result : %s \n",ms.doFunc());
		}
		
	}	
}

@AnnoFish
class Shark{	
	public String doFunc() {
		return "doFunc";
	}
}



class Eagle{
	
	@AnnoBird(name = "EAGLE")  // value 는 기본값이다. WebServlet("/index"), RequestMapping("/index")
	public String doFunc() {
		return "We are Bird Familly";
	}
}

 


4. 스프링 웹 MVC 의 주요 애너테이션 

Spring Api : https://docs.spring.io/spring-framework/docs/current/javadoc-api/

org.springframework.stereotype
@Component
@Controller
@Indexed
@Repository
@Service

org.springframework.beans.factory.annotation
@Autowired;

 


~ ing

 

※ 리플렉션(Reflection)  : 런타임에 클래스의 메타 정보를 얻는 기능
    - 클래스가 가지고 있는 필드, 생성자, 메소드, 어노테이션 정보를 얻을 수 있다.
    - 런타임시에 어노테이션 정보를 얻을려면 유지 정책을 RUNTIME 으로 설정해야 한다.

 


참고 블로그
    https://jhparkkk.tistory.com/3
    https://hongsii.github.io/2018/12/12/java-annotation/
    https://jktech.tistory.com/28
    https://elfinlas.github.io/2017/12/14/java-annotation/
    https://prinha.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-annotation%EC%9D%98-%EC%A0%95%EC%9D%98%EC%99%80-%EC%A2%85%EB%A5%98
   https://gyrfalcon.tistory.com/entry/Java-Reflection 

 

참고 유튜브

  https://www.youtube.com/watch?v=BNehTHmf0HQ&list=PL2lVRutSfJd_84EoQ_4YrXDZFTZ-nfbxy&index=93 

https://www.youtube.com/watch?v=GQYoIl9sOlk 

https://www.youtube.com/watch?v=zNmq-qGzsUY&t=468s