Annotation
java 를하고
Spring 처음 했을때 멘붕이였던 기억이있다.
저기 위에달린 @AutoWired 는 뭐지 ? 하고 그냥 안되니까 붙여서 사용했다.
생각해보면 @Override @Overloading @SuppressWarings있었지만 이것만 있겠지 생각했던 거 같다.
원리를 이해하면 좋을거같아 찾아보고 정리하려한다.
어노테이션 이란?
어노테이션은 사전적 의미로는 주석이라는 뜻이다.
자바에서 사용될 때의 어노테이션은 코드 사이에 주석처럼 쓰여서 특별한 의미,
기능을 수행하도록 하는 기술이다.
즉, 프로그램에게 추가적인 정보를 제공해주는 메타데이터(meta data: 데이터를 위한 데이터)라고 볼 수 있다.
# 메타데이터: 컴파일 과정과 런타임 에서 코드를 어떻게 컴파일하고 처리할 것인지에 대한 정보
그리고 메타 데이터이기 때문에 비즈니스 로직에 직접적인 영향을 주진 않지만,
이 메타데이터 정보에 따라서 실행 흐름을 변경할 수 있는 코딩이 가능하고
어노테이션 추가만으로 더 깔끔한 코딩이 가능하다.
Java 5부터 추가된 기능이다.
어노테이션 용도
- 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공
- 소프트웨어 개발툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보제공
- 실행시(런타임시) 특정 기능을 실행하도록 정보를 제공
어노테이션을 통해 우리는 AOP(Aspect Oriented Programimg , 관심 지향 프로그래밍) 을 구성 가능하다.
어노테이션은 컴파일시기에 처리가능, 자바의 리플렉션을 거쳐서 런타임에 처리 가능
#리플렉션: 실행중인 자바 클래스의 정보를 볼 수 있게 하고, 그 클래스의 구성 정보로 기능을 수행가능
커스텀 어노테이션
어노테이션의 필드 타입은 enum ,String이나 기본 자료형,기본 자료형의 배열만 사용 가능
@Target({ElementType.[적용대상]})
@Retention(RetentionPolicy.[정보 유지되는 대상])
public @interface [어노테이션 명]{
public 타입 elementName() [default 값]
....
}
메타 어노테이션이란?
커스텀 어노테이션을 구성할 때 시점,위치등을 지정하기 위한 어노테이션이다.
@Retention: 컴파일러가 어노테이션을 다루는 방법을 기술, 어느 시점까지 영향을 미치는지를 결정
RetentionPolicy.SOURCE : 컴파일 전까지 유효
RetentionPlicy.CLASS : 컴파일러가 클래스를 참조할 때 까지 유효
RetentionPlicy.RUNTIME : 컴파일 이후 런타임 시기에도 JVM에 의해 참조가 가능 (리플렉션)
@Target : 어노테이션 적용할 위치 선택
ElementType.PACKAGE : 패키지 선언
ElementType.TYPE : 타입선언
ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
ElementType.CONSTRUCTOR : 생성자 선언
ElementType.FIELD : 멤버 변수 선언
ElementType.LOCAL_VARIABLE : 직역 변수 선언
ElementType.METHOD : 메서드 선언
ElementType.PARAMETER : 전달인자 선언
ElementType.TYPE_PARAMETER: 전달인자 타입 선언
ElementType.TYPE_USE : 타입선언
@Documented : 해당 어노테이션을 Javadoc에 포함시킴
@Inherited : 어노테이션의 상속을 가능하게함
@Repeatable : Java8부터 지원, 연속적으로 어노테이션을 선언 할 수 있게 함.
어노테이션 동작원리 및 예제
어노테이션 타입선언은 특별한 종류의 인터페이스로 인식한다.
선언은 @interface 를 붙여 선언
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface CustomAnnotation {
public String value();
}
위의 커스텀 어노테이션을 JDK 내장 javap라는 역어셈블러를 사용해 확인해보면
public interface annotation.CustomAnnotation extends java.lang.annotation.Annotation{
public abstract java.lang.String value();
}
@interface는 자동으로 Annotation 클래스를 상속하고 내부의 메소드들은 abstract 키워드가 자동으로 붙게된다.
따라서 어노테이션 인터페이스는 extends 절을 가질 수 없으며, 추가적인 제약이있다.
- 어노테이션 타입 선언은 제네릭일 수 없다.
- 메소드는 매개변수를 가질 수 없다.
- 메소드는 타입 매개변수를 가질 수 없다.
- 메소드 선언은 throws절을 가질 수 없다.
Spring 의 어노테이션
스프링은 @Component, @Service, @Controller, @Repository 등등 수많은 어노테이션을 지원한다.
@Component의 구조
@Target({ElementType.TYPE})
@Retemtoion(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component{
String value() default "";
}
코드 작성 시 @Component 어노테이션을 붙인 클래스를 하나 작성했다면,
이제 스프링은 구동 단계에서 ClassPathBeanDefinitionScanner.java 의 다음 메소르
protected Set<BeanDefinitionHolder> doScan(String... basePackages{...}
를 사용해 ClassPath내에 있는 패키지의 모든 클래스를 읽어
어노테이션이 붙은 클래스에 대해 컨테이너에 빈 등록 등의 작업을 수행 하고
런타임 시에 자동으로 의존성 주입 등에 사용가능.
커스텀 어노테이션 만들기
PersonInfo.java
클래스 생성시 인스턴스를 생성하여 런타임 시 어노테이션을 읽어 mention출력
PersonInfo.java
Person.java
QutePerson.java
PersonService.java
출력값
#같이 보면 좋은 글
우아한 형제들 커스텀 annotation 사용
https://techblog.woowahan.com/2684/
#참고
https://www.nextree.co.kr/p5864/
Java Annotation: 인터페이스 강요로부터 자유를…
작년에 했던 프로젝트에서 Spring Annotation과 JAXB Annotation을 사용한 경험이 있습니다. Annotation을 이용해서 객체의 속성을 매핑하는데 유용하게 사용했던 기억이 나네요. 하지만 최근에 Annotation에
www.nextree.co.kr
https://advenoh.tistory.com/21
자바 커스텀 어노테이션 만들기
1. 어노테이션이란 스프링 프레임워크를 사용하면 어노테이션을 자주 사용하게 됩니다. 아래는 스프링 웹 MVC를 사용한 예로 GET HTTP 요청(/helloworld)이 있으면 “Hello World”를 담아서 뷰에 전달되
advenoh.tistory.com
[Java] 어노테이션 (+커스텀 어노테이션 만들기)
자바 어노테이션에 대한 간략한 이해와 커스텀 어노테이션 만들어서 사용하는 법을 araboza
velog.io