Java

[Gradle] 의존성 설정과 컴파일/런타임 시점의 이해(feat.Lombok)

연신내고독한늑대 2024. 9. 30. 20:00

의존성 설정을 올바르게 사용하기 위해 꼭 알아야 할 두 가지 개념인 컴파일 시점타임 시점의 차이를 자세히 살펴보겠습니다. 이러한 차이를 이해하는 것이 compileOnly, runtimeOnly, annotationProcessor와 같은 설정을 올바르게 사용하는 데 매우 중요합니다.

 

컴파일 시점과 런타임 시점이 무엇인지, 그리고 이 시점들이 Gradle의 의존성 설정과 어떻게 연관되어 있는지 알아본 후, 컴파일 시점에 주로 사용하는 compileOnly와 annotationProcessor의 차이점에 대해서도 다루어보겠습니다. 이를 통해 여러분의 프로젝트에서 최적화된 의존성 관리를 구현하는 방법을 배울 수 있을 것입니다.

 

■ 컴파일 시점과 런타임 시점이란?

 

1. 컴파일 시점 (Compile-Time)

 

  • 설명: 컴파일 시점은 소스 코드가 자바 컴파일러에 의해 바이트코드(.class 파일)로 변환되는 단계입니다. 이 시점에는 소스 코드의 문법 오류를 확인하고, 필요한 코드를 자동으로 생성하는 작업이 수행됩니다.
  • 언제 발생하나?: 컴파일 시점은 개발자가 소스 코드를 작성하고, gradle build 또는 gradle compileJava 명령을 실행할 때 발생합니다.
  • 스프링과의 관계: 스프링 프레임워크는 대부분의 작업을 런타임에 수행하지만, 일부 애노테이션 검증이나 설정 오류를 컴파일 시점에 확인합니다.

2. 런타임 시점 (Runtime)

 

  • 설명: 런타임 시점은 컴파일된 바이트코드가 JVM에 의해 실제로 실행되는 단계입니다. 이 단계에서는 스프링 컨테이너가 동적으로 빈(bean)을 생성하고, 의존성을 주입하며, 애플리케이션의 로직이 수행됩니다.
  • 언제 발생하나?: gradle bootRun이나 java -jar 명령으로 애플리케이션을 실행할 때 런타임 시점이 시작됩니다.
  • 스프링과의 관계: 스프링은 런타임에 주로 동적으로 빈을 관리하고 의존성을 주입하며, 설정 파일을 읽어와 애플리케이션 환경을 구성합니다.

 

■ compileOnly와 annotationProcessor의 차이점

컴파일 시점에 사용되는 설정에는 compileOnly와 annotationProcessor가 있습니다. 둘 다 컴파일 시점에 작동하지만, 정확한 용도와 역할이 다릅니다. 이 차이를 알아두면 적절한 의존성 설정을 통해 효율적인 빌드를 구성할 수 있습니다.

 

1. compileOnly

용도: 컴파일 시점에만 필요한 의존성을 지정합니다. 런타임에는 필요하지 않으며, 주로 애노테이션이나 인터페이스와 같이 코드의 구조에만 영향을 주는 라이브러리에 사용됩니다.

// 예시
compileOnly 'org.projectlombok:lombok'

Lombok은 컴파일 시점에 애노테이션을 기반으로 자동으로 게터와 세터 메서드를 생성하지만, 런타임에서는 더 이상 Lombok이 필요하지 않습니다. 따라서 compileOnly를 사용하여 컴파일 시점에만 Lombok을 참조하도록 합니다.

 

2. annotationProcessor

용도: 애노테이션 프로세서를 통해 컴파일 시점에 코드를 생성하거나 변환하는 작업을 수행할 때 사용됩니다. 이 설정을 통해 컴파일러는 특정 애노테이션을 처리해 자동으로 필요한 코드를 생성합니다.

// 예시
annotationProcessor 'org.projectlombok:lombok'

Lombok의 @Getter, @Setter 등 애노테이션은 컴파일 시점에 코드를 생성합니다. 이를 위해 annotationProcessor 설정을 통해 Lombok의 애노테이션 프로세서를 등록해야 합니다. 그렇지 않으면 Lombok 애노테이션이 작동하지 않게 됩니다.

 

■ Lombok 사용 시 compileOnly와 annotationProcessor 둘 다 필요한 이유

 

  • compileOnly: Lombok 애노테이션을 컴파일 시점에 참조할 수 있도록 합니다.
  • annotationProcessor: Lombok 애노테이션 프로세서를 사용해 컴파일 시점에 실제로 코드를 생성하는 작업을 수행합니다.

 

 

■정리: 의존성 설정을 왜 구분해야 하는가?

 

  • 빌드 최적화: 컴파일 시점과 런타임 시점을 명확히 구분하여 필요한 의존성만 포함함으로써 빌드 시간을 줄이고 최종 애플리케이션 크기를 최소화할 수 있습니다.
  • 의존성 관리의 명확성: compileOnly와 annotationProcessor와 같은 설정을 통해 코드의 의도를 명확하게 전달할 수 있으며, 유지보수 시 의존성 관리를 쉽게 할 수 있습니다.
  • 최종 빌드 크기 감소: 필요한 라이브러리만 런타임에 포함하여, 최종 배포 파일의 크기를 줄이고 애플리케이션의 성능을 향상시킬 수 있습니다.