Annotation에 관해서

조성현·2023년 3월 10일
0

Spring

목록 보기
2/4
post-thumbnail

서론

스프링을 자주 사용할 경우 어노테이션 사용이 많아지는 데, 정작 어노테이션에 관해서 깊이 알아보지 않고 이 어노테이션을 넣으면 이렇게 동작한다고 하니 넣어야지 식으로 그냥 넣고 있었다는 것을 깨달았습니다.

이번 기회에 어노테이션이라는 것을 깊이 알아보고, 이를 통해 알게 된 것을 작성해 보는 시간을 가졌습니다.


🖊 어노테이션이란?

자바 어노테이션(Java annotation)은 이렇게 설명할 수 있습니다.

자바 소스코드에 추가해서 사용할 수 있는 메타 데이터의 일종입니다. 보통 @ 기호를 앞에 붙여서 사용하며. JDK 1.5 버전 이상에서 사용 가능합니다.

메타 데이터란?
프로그램이 처리할 메인 데이터가 아니라
컴파일 과정과 실행 과정에서 코드를 어떻게 처리해야 하는 지에 관한 추가 정보를 가지고 있는 서브 데이터 라고 정의할 수 있습니다.


🖊 어노테이션의 사용 용도 3가지

어노테이션은 크게 3가지 용도로 사용됩니다.

  1. 코드 문법 에러 체크
  2. 코드 자동 생성 정보 제공
  3. 런타임 시 특정 기능을 실행하는 정보 제공

🖊 어노테이션의 사용 방식 3가지

그리고 어노테이션은 크게 3가지 방식으로 사용하는 데

  1. Built-in annotation
  2. Meta annotation
  3. Custom annotation

이 중 세 번째인 Custom annotation은 Meta annotation을 사용해서 만들어 집니다.


📕 built-in annotation

자바에서 기본적으로 제공하는 어노테이션들인데, 이 중 많이 사용하는 어노테이션은

  1. @Override
  2. @Deprecated
  3. @SuppressWarnings

@Override

메소드가 슈퍼클래스의 메소드를 오버라이드한 메소드라는 정보를 컴파일러에게 전달한다.

메서드를 상속받을 때 메서드 이름을 잘못 적거나 해당 메서드가 없을 때 에러 메시지를 띄웁니다.

	class Parent{
		void parentMethod(){}
	}

	class Child extends Parent{
		@Override
    	void pparentmethod(){} // 컴파일 에러! 잘못된 오버라이드 스펠링 틀림
    }

@Deprecated

버전업을 하면서 해당 클래스 / 메소드 등이 지원되지 않을 수 있기 때문에 더 이상 사용하지 말라는 경고 메세지를 알려준다.

	@Deprecated
	public void deprecatedMethod() {
    	System.out.println("test");
	}

@SuppressWarnings

코드의 대한 오류경고가 발생할시 컴파일러에게 명령을 내려 발생하는 경고를 제거한다.

@SuppressWarnings 어노테이션은 옵션을 가지는 데, 옵션에 따라 다음과 같은 기능을 가집니다.

  • @SuppressWarnings("all") : 모든 경고 억제

  • @SuppressWarnings("cast") : 타입 캐스트 관련 억제

  • @SuppressWarnings("dep-ann") : 사용하지 말아야 할 주석 관련 억제

  • @SuppressWarnings("deprecation") : @Deprecated 사용 시 발생하는 경고 억제

  • @SuppressWarnings("fallthrough") : switch 문에서 break 구문 누락 관련 경고 억제

  • @SuppressWarnings("finally") : finally 블럭 관련 억제

  • @SuppressWarnings("null") : null 관련 경고 억제

  • @SuppressWarnings("rawtypes") : 제네릭을 사용하는 클래스 매개변수가 특정 되지 않았을 때 경고 억제

  • @SuppressWarnings("unchecked") : 검증되지 않은 연산자 관련 경고 억제

  • @SuppressWarnings("unused") : 사용하지 않는 코드 관련 경고 억제

경고 상황을 알고 있을 때, 컴파일 로그가 지저분 해지고, 진짜 필요한 경고가 잘 보이지 않을 수 있기 때문에 이 어노테이션을 사용합니다.


📕 Meta annotation

@Retention

어노테이션이 유지되는 기간을 지정하는 데 사용합니다.

  • RetentionPolicy.Class : 바이트 코드 파일까지 어노테이션 정보를 유지합니다.

  • RetentionPolicy.Runtime : 런타임 까지 어노테이션 정보를 유지합니다.

  • RetentionPolicy.Source : 소스 파일까지 어노테이션 정보를 유지합니다.

@Retention 어노테이션이 어떤 식으로 작동하는 지는 해당 링크에 자세히 나와있습니다.
아무 관심 없던 @Retention 어노테이션 정리(RetentionPolicy SOURCE vs CLASS vs RUNTIME)

@Documented

자바 문서에 포함시킬 때 해당 어노테이션을 사용합니다.

@Target

생성할 어노테이션이 적용될 수 있는 위치를 나열합니다.

@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 : 타입 선언

@Inherited

자식 클래스가 어노테이션을 상속 받을 수 있습니다.

@Repeatable

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


📕 Custom annotation

기본적으로 자바에 있는 어노테이션이 아니라 저희가 직접 어노테이션을 만들 수 있습니다.

	@interface 이름 {
    	타입 요소 이름(); // 어노테이션의 요소를 선언
    }

주의점

위와 같은 방식으로 어노테이션을 선언해도 런타임 시 컴파일러가 해당 코드를 읽지 못합니다.

따라서 런타임 시 클래스의 메타 정보(어노테이션)를 읽어 주는 기능인 리플렉션(@Reflection)을 추가 선언 해주어야 하는데

런타임 시 어노테이션 정보를 얻을려면 어노테이션 유지정책을 RUNTIME으로 설정해야 합니다. 그러기 위해서는 메타 어노테이션 중 하나인

@Retention(RetentionPolicy.RUNTIME)

을 사용하면 됩니다.

어노테이션을 생성할 때, 해당 어노테이션 안에 메서드를 넣을 수 있는데, 그것을 element(요소) 라고 합니다. 요소의 개수에 따라서 Marker, Single-value, Full 어노테이션으로 분류할 수 있습니다.

  • Marker Annotation : 요소가 없으면 단순하게 표식으로 사용되는 어노테이션, 컴파일러에게 어떤 의미 전달체로 사용
  • Single-value Annotaion : 요소가 한가지인 어노테이션, 단일변수 밖에 없기에 값만을 명시하여 데이터 전달이 가능하다
  • Full Annotaion : 요소가 둘 이상의 변수를 갖는 어노테이션, 데이터를 배열 안에 key-value 형태로 전달한다

annotation 규칙

  1. 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용된다.
  2. 괄호()안에 매개변수를 선언할 수 없다.
  3. 예외를 선언할 수 없다.
  4. 요소의 타입을 매개변수로 정의할 수 없다. ex) < T >
	@interface AnnoConfigTest{
    int id = 10; // 상수 ok
    String make(int i, int j) //매개변수 x
    String minor() throws Exception; // 예외 x
    ArrayList<T> list(); // 요소의 타입을 매개변수 x

🎓 마치며

어노테이션을 깊게 알아보기 위해서 공부를 한 결과, 많은 궁금증이 해결이 되었으나 이론으로만 아는 것이기 때문에 실제로 적용해보면서 더 많이 알아가야겠다고 생각하였습니다.
Spring을 사용해보면서 많은 어노테이션을 적용해보면서 부족한 내용이 있을 경우 더 보충할 것 같습니다.

참고

[Java] 자바 어노테이션 사용법 및 예제
[Java] 어노테이션이 뭔데??
Java @어노테이션이란?

profile
평범한 개발자의 글

0개의 댓글

관련 채용 정보