pile·
백엔드·야놀자 클라우드야놀자 클라우드·

java 코드는 어떻게 자동으로 만들어질까(1/2)

Lombok 설정에서 늘 켜기만 하고 넘어갔던 annotation processing이 무엇인지 파고든 글이다. 사수와의 대화로 시작해 어노테이션 프로세서의 정의와 동작 시점을 짚고, 엔티티에서 DTO를 생성하는 커스텀 프로세서를 직접 만들어본다. Lombok이 왜 새 클래스를 만들지 않는지는 2부로 넘긴다.

핵심 포인트
  • 어노테이션 프로세서는 자바 컴파일러가 제공하는 기능으로 컴파일 단계에서 코드를 검사하고 조작하거나 생성한다.
  • Lombok뿐 아니라 코드를 자동 생성하는 라이브러리 대부분이 이 단계에서 만들어낸다고 보면 된다.
  • IDE의 annotation processing 체크박스와 빌드 설정이 무엇을 켜는 것인지가 여기서 설명된다.
  • 얻는 이득은 getter나 setter 같은 반복되는 보일러플레이트 코드를 줄이는 것이다.
  • 실제 코드 생성은 JavaPoet 같은 라이브러리로 클래스와 패키지, 생성자, 필드까지 조립한다.
  • Lombok은 새 클래스를 만들지 않고 바이트코드 수준에서 코드를 조작한다는 점이 다르다.
상세 정리
  • 도입부: 주니어 시절 사수에게 어노테이션 프로세서를 아느냐는 질문을 받고 Lombok 설정에서 본 체크박스만 떠올렸던 대화로 시작한다.
  • 문제의식: 그 옵션이 무엇이고 Lombok이 어떻게 동작하는지 알면 개발할 때 시야가 넓어진다고 본다.
  • 어노테이션의 정의: 오버라이드 표기처럼 쓰는 메타성 데이터의 일종이다.
  • 단서: 그 어노테이션 정의를 열어보면 적용 대상과 유지 정책이 지정돼 있어, 어노테이션으로 무언가를 처리한다는 추측이 가능해진다.
  • 프로세서의 정의: 특정 어노테이션을 기반으로 컴파일 단계에서 코드를 검사하고 조작하거나 생성하게 해주는 컴파일러 기능이다.
  • 이미 쓰고 있는 것들: 쿼리 빌더 계열처럼 코드를 자동 생성하는 라이브러리 대부분이 이 단계를 쓴다.
  • 이득: 단순 중복 코드, 이른바 보일러플레이트를 줄인다. Lombok을 썼을 때의 이점을 떠올리면 바로 와닿는다.
  • 예제 설계: JPA를 쓰면 엔티티 클래스와 DTO 클래스가 각각 존재하고 구조가 비슷한 경우가 많다는 데서 착안했다.
  • 예제 목표: 엔티티 클래스를 기반으로 생성자와 getter를 가진 DTO 클래스를 자동 생성하는 기능을 만든다.
  • 사용 방법: 평범한 엔티티 클래스에 커스텀 어노테이션을 붙이고 컴파일하면 생성 경로에 DTO 클래스가 만들어진다.
  • 생명주기: clean하면 사라지고 컴파일 시점에 다시 생성되는 것을 확인할 수 있다.
  • 구현 1: 프로세서의 추상 클래스를 상속한 구현체가 필요하며, 지정한 어노테이션이 붙은 클래스를 찾는 역할을 한다.
  • 구현 2: 찾은 클래스를 바탕으로 새 코드를 만들며, 이때 JavaPoet을 쓰면 클래스 이름과 패키지, 생성자, 메서드, 필드, 어노테이션까지 조립할 수 있다.
  • 실무에서의 위치: 직접 만들어 쓸 일은 많지 않다고 인정한다. 대부분 이미 잘 만들어진 라이브러리가 있고, 직접 만들면 설정과 수정 비용이 더 커질 수 있다.
  • 그럼에도 알아야 하는 이유: 알고 안 쓰는 것과 몰라서 못 쓰는 것은 다르며, 최소한 이런 기능을 쓰는 라이브러리가 있는지 찾아볼 수 있게 된다.
  • 남은 의문: Lombok은 새 클래스가 생기지 않는데 어떻게 된 것이냐는 질문을 스스로 던진다.
  • 2부 예고: Lombok은 새 클래스를 만드는 대신 바이트코드 레벨에서 코드를 조작한다고 밝히고 다음 편으로 넘긴다.
왜 읽나Lombok을 쓰면서 annotation processing 체크박스를 왜 켜는지 모르고 넘어갔다면, 그 옵션이 무엇을 켜는 것이고 그 위에서 무엇을 만들 수 있는지 예제로 확인할 수 있다.
야놀자 클라우드
야놀자 클라우드 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·twilio-engTwilio Engineering·

    Programmable Messaging에서 Verify API로 마이그레이션하기

    Twilio의 Programmable Messaging API로 자체 OTP 솔루션을 운영하던 서비스가 Verify API로 전환하는 방법을 코드 예시와 함께 설명한다. Verify는 OTP 전송·검증을 위한 전용 API로, 전화번호 구매, 토큰 생성, DB 저장·만료 관리를 내부에서 처리해 개발자가 직접 구현할 코드를 크게 줄인다.

    요약 이어보기
    #authentication#twilio#sms+2
  2. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 2부

    포스타입 백엔드 엔지니어가 벡터 기반 개인화 추천 시스템을 실제 운영하며 맞닥뜨린 성능 장애와 용량 문제를 해결한 과정을 담은 2부다. 수백만 개의 벡터 KNN 검색이 피크 시간대에 전체 Elasticsearch 검색 성능을 흔드는 문제부터 클러스터 OOM 사태까지, 쿼리 최적화와 인프라 분리 두 가지 경로로 근본 해결에 이른다.

    요약 이어보기
    #elasticsearch#vector-search#recommendation-system+2
  3. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 1부

    포스타입이 태그 기반 추천의 한계를 극복하고 벡터 임베딩 기반 개인화 추천 시스템을 구축한 과정을 담은 1부다. 유사한 콘텐츠가 다른 용어를 쓰거나 동일한 태그가 전혀 다른 톤의 콘텐츠를 가리키는 문제를 임베딩 벡터로 해결하고, OpenSearch의 HNSW ANN 검색으로 수백만 벡터를 실시간 검색하는 시스템을 구축해 구매율 15% 향상을 달성했다.

    요약 이어보기
    #opensearch#vector-search#recommendation-system+2