학습목표 : 자바 어노테이션을 이해하고 그 종류에 대해 공부한다.
사전적 의미
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 | 어노테이션이 적용가능한 대상을 지정하는데 사용한다.
|
@Documented | 어노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다. |
@Inherited | 어노테이션이 자손 클래스에 상속되도록 한다. |
@Retention | 어노테이션이 유지되는 범위를 지정하는데 사용한다. (SOURCE, CLASS, RUNTIME)
|
@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
'Java' 카테고리의 다른 글
[Javadoc] 이클립스에서 javadoc 간단생성 (1) | 2021.05.17 |
---|---|
[instanceof] 나는 어디 소속인가? (0) | 2021.05.12 |
final 키워드에 대한 고찰 (0) | 2021.05.11 |
[Interface & Extends] 이 둘의 단순하지만 OOP적인 Collaboration (0) | 2021.05.06 |
[Interface] 인터페이스에 대한 수준낮은 고찰 (0) | 2021.04.28 |