개요
회사에서 스프링 부트 프로젝트 버전업 업무를 진행하며 Gradle 버전까지 함께 올려야 할 일이 생겼다. 기존에는 Gradle 5 버전을 사용했는데 8 버전으로 올리며 자료조사를 하던 중 기존 방식과 차이를 발견하여 해당 내용을 정리한다.
Gradle은 3.4 버전부터 api와 implementation이라는 새로운 키워드를 도입하며 의존성 관리 방식을 개선했다. 이전에는 compile이라는 단일 키워드로 모든 의존성을 처리했지만, 빌드 성능 최적화와 의존성 관리의 명확성을 위해 compile은 Gradle 7.0에서 완전히 deprecated(사용 중단)되었다. 이번 글에서는 Gradle의 api와 implementation의 차이를 알아보고, 각각을 언제 어떻게 사용하는지 정리해 보려고 한다.
api란?
api는 의존성을 현재 모듈뿐만 아니라 다른 모듈에서도 사용할 수 있도록 노출하는 키워드이며, 이는 의존성이 현재 모듈의 공개 API의 일부로 간주될 때 적합하다.
특징
- 의존성 노출:
- 현재 모듈의 의존성이 이 모듈을 사용하는 다른 모듈에서도 가시성을 가짐.
- 컴파일 클래스 경로:
- 의존성에 포함된 클래스가 다른 모듈에서도 컴파일 타임에 접근 가능.
- 사용 예시
dependencies {
api 'com.google.guava:guava:31.0.1-jre'
}
이 경우, guava 라이브러리는 현재 모듈뿐만 아니라 의존하는 모든 모듈에서 사용 가능.
언제 사용할까?
- 현재 모듈이 제공하는 API가 의존성 클래스에 강하게 의존할 때 사용.
- 예를 들어, 라이브러리나 SDK를 개발하는 경우에 적합.
implementation이란?
implementation은 의존성을 현재 모듈 내부에서만 사용할 때 사용하는 키워드이며 즉, 이 의존성은 다른 모듈에 노출되지 않으며, 내부 구현에만 사용되는 의존성을 정의할 때 적합.
특징
- 의존성 비노출:
- 의존성은 현재 모듈 내부에서만 사용 가능하며, 다른 모듈에서는 접근 불가.
- 컴파일 클래스 경로:
- 의존성은 현재 모듈의 컴파일 클래스 경로에만 포함.
- 성능 최적화:
- 컴파일 타임에 불필요한 의존성을 줄이므로 빌드 속도와 메모리 사용량이 개선.
- 사용 예시
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
이 경우, commons-lang3 라이브러리는 현재 모듈에서만 사용 가능하며, 다른 모듈에서는 접근할 수 없음.
언제 사용할까?
- 의존성이 현재 모듈의 내부 구현에만 사용되는 경우.
- 모듈 외부에서 해당 의존성 클래스를 직접 사용할 필요가 없는 경우.
api와 implementation의 차이점
특징 | api | implementation |
의존성 노출 범위 | 현재 모듈과 의존하는 다른 모듈에서도 사용 가능 | 현재 모듈에서만 사용 가능 |
컴파일 클래스 경로 | 현재 모듈과 의존하는 다른 모듈 모두 포함 | 현재 모듈에서만 포함 |
빌드 성능 | 의존성 노출로 인해 빌드 시간이 증가할 수 있음 | 컴파일 클래스 경로가 작아져 빌드 속도 개선 |
사용 사례 | 라이브러리, SDK 등 외부 API를 노출할 때 | 내부 구현에만 필요한 의존성을 정의할 때 |
실제 사용 예제
프로젝트 구조
project
├── moduleA
├── moduleB
- moduleA는 guava와 commons-lang3 라이브러리를 사용
- moduleB는 moduleA에 의존
moduleA의 build.gradle
dependencies {
api 'com.google.guava:guava:31.0.1-jre' // 노출됨
implementation 'org.apache.commons:commons-lang3:3.12.0' // 비노출
}
결과
- moduleB는 guava 라이브러리를 사용 가능. (api로 선언했기 때문)
- 그러나 commons-lang3는 사용 불가능. (implementation으로 선언했기 때문)
언제 api와 implementation을 사용할까?
- 기본적으로 implementation을 우선 사용. 이는 빌드 성능을 개선하고 불필요한 의존성 노출을 방지할 수 있음.
- api는 라이브러리나 SDK와 같이 외부에 공개해야 할 API를 포함한 의존성을 정의할 때만 사용.
결론
Gradle의 api와 implementation은 의존성을 관리할 때 중요한 키워드이다. api는 의존성을 외부 모듈에 노출할 때 사용하며, implementation은 내부 구현에만 필요한 경우 사용된다. 올바르게 사용하면 빌드 성능을 최적화하고 코드의 의존성 관리를 깔끔하게 유지할 수 있으므로, 프로젝트의 특성과 요구사항에 맞게 적절히 선택하여 사용하면 좋을 것 같다.
'TIL' 카테고리의 다른 글
Optional.ifPresentOrElse로 자바의 조건 분기 깔끔하게 처리하기 (0) | 2024.11.19 |
---|---|
오라클 SQL 성능 개선하기: 스칼라 서브쿼리 vs 인라인 뷰 (0) | 2024.11.11 |
@RequestBodyAdvice로 Spring API 데이터 전처리와 후처리 완벽히 관리하기 (1) | 2024.11.05 |
스프링부트 @ConfigurationProperties 매핑 오류(null) (2) | 2024.10.15 |
Spring Boot에서 Multipart 파일 업로드 시 파일 크기 제한 오류(MaxUploadSizeExceededException ) (0) | 2024.09.30 |
댓글