본문 바로가기
가치관 쌓기/개발 돌아보기

잘 알아보고 사용하자 Java Annotation(주석)

by simplify-len 2024. 3. 10.

오픈소스를 개발하면서 @AggregateId 라는 필드를 추가할 적이였다. Id 에 대해서 자동생성시키기 위한 @AggregateId(assignStrategy=AUTO or MANUAL) 같이 만들고자 했으나, 그렇게 하면 안될 것 같다는 피드백을 받았다.

왜일까?

Java 에서 쓰이는 Annotation 은 무엇인가?

위키 백과 따르면 다음과 같다. 

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

여기서 말하는 메타데이터는 무엇일까?

메타데이터(metadata or metainformation)는 데이터(data)에 대한 데이터이다. 이렇게 흔히들 간단히 정의하지만, 캐런 코일(Karen Coyle)에 의하면 '어떤 목적을 가지고 만들어진 데이터(constructed data with a purpose)'라고도 정의한다. 즉, 다른 데이터를 정의하고 기술하는 데이터(data that defines and describes other data)이다.

쉽게 정의하면, 데이터를 설명하기 위해 만들어진 데이터이다.

그렇다면 우리가 Java Annotation 은 어디에 쓰였을까?
우리가 가장 많이 보는 곳은  @Override 이다. @Override는 객체지향프로그래밍에서 해당 메소드는 상위 클래스에 정의된 메소드가 있고, 해당 메소드를 재정의한다는 의미를 가진다. 우리는 방금 @Override 를 보고 메소드를 다시 해석할 수 있었다.

다른 애노테이션 하나만 더 살펴보자.
@SuppressWarnings({"unused"}) 해당 주석은 명명된 컴파일러 경고를 나타내기 위해 사용한다. 그럼 애노테이션은 어떤가? 우리는 해당 주석을 보고 어떤 경고가 있을지 사전에 인지할 수 있다.

충분히 메타데이터의 역할을 하고 있다는 생각이 든다. 이 글을 읽고 있는 사람들은 어떤지 궁금하다.

그럼 여기서 약간의 변종을 던져보면 우리가 많이 사용하는 Lombok 의 @Getter 이다.
특정 Object에 @Getter 를 붙이게 되면 특정 Object의 GetXX 메소드가 바이트 변환시 자동으로 생성된다.

여기서부터 Java 의 Annotation 이 맞다고 판단되는가? 정석대로 생각한다면, @Getter 는 Java의 Annotation 가 태어난 이유에 부합하지 않다. 그렇다면 잘못된걸까? 그렇지 않을 수 있다.

 Java 라는 프로그래밍 언어는 29년전 제임스고슬링에 의해서 만들어져 지금까지 진화된 언어이다. 무수히 많은 프로그래밍 언어 중에서 지금까지 살아남을 수 있었던 이유는 상황에 맞쳐 프로그래밍 언어가 생물처럼 변화해 왔기 때문일 것이다. 상황에 맞쳐 변화가 시도된 것에는 Java Annotation 도 포함될 수 있을 것 같다.  

우리가 lombok의 @Getter 를 사용함으로써 얻을 수 있는 이점은 무엇이였을까? 관례적으로 사용하던 Get/Set 메소드를 개발자가 더이상 작성하지 않아도 된다. 단 한 줄의 코드로 불편하다고 느꼈던 부분을 해소할 수 있게되었다. 

Lombok 와 같은 라이브러리가 점차 많아지면서 Java Annotation의 태어난 목적과는 다르지만 개발자에게 편의성을 제공하는 것은 사실이다. 편의성을 제공해주는 Annotation 은 괜찮을까? 문제가 없는걸까?

지금까지 Java Annotation 은 2가지 역할을 하고 있다고 말했다.

  • 데이터를 위한 데이터
  • 편의성 제공

다음으로 이야기하고 싶은 Annotation 은 Spring Boot의 @SpringBootApplication / @Service / @Components 애노테이션이다. 이것들은 어떤가?

데이터를 위한 데이터인가? 편의성을 제공하기 위한 용도인가? 나의 생각은 편의성을 제공할 수도 제공하지 않을 수도 있다는 생각이 든다. 아마도 Spring Boot 개발해본 사람들은 @SpringBootApplication 에서 제공하는 아래 그림과 같은 다양한 키워드를 알아야만 한다는 사실을 알게 된다.

@SpringBootApplication 에 대한 키워드

내부 동작원리에 대해서 이해하고 사용해봐야지만 이해할 수 있고, 해당 Annotation 만 봐서는 결코 이해하기 쉽지 않다. 스프링부트의 Annotation 형태의 개발 방법은 분명 개발자의 허들을 낮쳐줬다. 쉽고 빠르게 개발할 수 있는 방법을 제공한다. 그러나 다른 관점에서는 스프링부트를 잘 활용하기 위한 허들을 높인다.

과거에 작성했던 Spring5 를 왜 사용해야되는건가?(with Tody Lee) 포스팅을 살펴보면 Spring 5에 대한 단점으로 Annotation을 언급하고 있습니다.
다음과 같은 문제점이 있다고 합니다.
- 컴파일러에의해 검증 가능한 타입이 아님
- 코드의 행위를 규정하지 않음
- 상속, 확장 규칙의 표준이 없음
- 이해하기 어려운 코드, 오해하기 쉬운 코드 가능성
- 테스트가 어렵거나 불가능함
- 커스터마이징하기 어려움

SpringBoot 에서 Annotation 이 사용된 것이 잘못된 것이다. 라고 말하고 싶은 것이 아니다. 다만 Java Annotation 의 무분별한 사용은 안좋은 개발자 경험을 할 수 있다는 것이다. 그러므로 우리는 신중하게 Annotation을 바라볼 필요가 있다는 생각이 든다.

다시 처음으로 돌아가서, @AggregateId(assignStrategy=AUTO or MANUAL) 은 왜 사용하면 안될 것 같다 는 이야기가 나왔을까? 특정 설정 정보가 파편화되어 사용하면 추후에 이것을 제어하는 관점에서 혼란이 가중될 수 있고, 무엇보다 이것은 편의성/데이터를 위한 데이터 목적으로 만들어졌다라고 보기 어렵기 때문이다.

댓글