익숙함
문득 웹 프로젝트 관련 내용들을 정리해나가면서, gradle 파일을 보니까 다음과 같은 부분이 눈에 들어왔다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
}
언제부턴가 기존 프로젝트를 따라가는 방식으로 라이브러리 의존성을 작성하다 보니까,
이것들에 대한 이해하고 있다는 확신이 들지 않아 정리가 필요해보여 글로 정리해본다.
일단 공식 홈페이지부터....
일단 공식 홈페이지의 그림 하나와 표를 가져와보자.
Gradle의 Dependency Configuration
초록색은 사용자가 의존성을 선언할 때 사용한다.
분홍색은 구성요소가 라이브러리를 컴파일하거나 실행할 때 사용한다.
파란색은 구성 요소 자체 사용을 위해 구성 요소 내부에서 사용한다.
그래프를 보면 우리가 궁금해하는 내용은 초록색에 해당하는 내용이지만,
파란색과 분홍색의 내용이 무엇인지 알아야 초록색에 대해서 이해할 수 있다.
apiElements
라이브러리 컴파일(Compile)
해당 라이브러리를 컴파일하는 데 필요한 모든 요소를 검색할 때 사용한다.
default 설정과 다르게, implemenation이나 runtime 의존성에 대한 정보를 노출하지 않는다.
runtimeElements
라이브러리 실행(Runtime)
해당 라이브러리를 실행하는 데 필요한 모든 요소를 검색할 때 사용한다.
compileClassPath와 runtimeClassPath는 우리가 알고 있는 그 classPath에 대한 내용이다.
그러면 다시 돌아와서, 아래 표와 그래프의 초록색 요소들에 대해 정리를 해보자.
api
컴파일 타임과 런타임에 사용자에게 의존성을노출시킨다.
의존 라이브러리가 수정되는 경우 본 모듈을 의존하는 모든 모듈들을 재빌드한다.
implementation
내부적으로만 사용되고 사용자에게는 의존성을 노출시키지 않게 선언한다.
다만, 런타임에는 노출된다.
의존 라이브러리를 수정해도 본 모듈까지만 재빌드한다.
결국, api와 implementation은 다음과 같은 차이를 가진다.
A <= B <= C의 구조를 가지는 모듈이 있다고 가정하자.
- A가 api면, C에서는 A 접근이 가능하며 A가 수정되면 B, C가 재빌드된다.
- A가 implemenation이면, C에서 A를 접근할 수 없고 A 수정 시 B까지만 재빌드한다.
compileOnly
컴파일 타임에 필요한 라이브러리
컴파일 시에만 빌드하고 빌드 결과물에는 포함하지 않는다.
compileOnlyApi
사용자가 만든 모듈에 의해 컴파일 타임에 필요한 라이브러리
compileOnly와 동일하게 컴파일 시에만 빌드하고 빌드 결과물에는 제외된다.
runtimeOnly
런타임 시점에만 필요한 라이브러리
annotationProcessor
annotation processor를 명시하기 위해 사용
그래서, 언제 무엇을 써야 하는가?
라이브러리마다 필요한 시점이 다르기 때문에 거기에 맞게 사용해야 한다.
가장 좋은 건 라이브러리마다 어떤 방식으로 제공하는지 이해한 후, 그에 맞게 사용해야 한다.
api는 의존 프로젝트를 전체 재빌들할만한 프로젝트 경험이 없어서 정리할 내용이 없고,
주로 사용하는 것들만 간단하게 정리해봤다.
implemenation
예전에 안드로이드를 잠깐 맛만 봤을 때 compile이 Deprecated되면서, 대부분의 implementation으로 변경했었다.
실제로 MVNRepository에서 의존성 추가하려고 예시를 가져오면 대부분 이것을 사용한다.
이 옵션은 대규모 빌드에서는 다시 컴파일을 진행할 때, 그 대상의 크기가 줄어 빌드 시간을 개선할 수 있다고 한다.
프로젝트에 어떤 라이브러리를 사용한다고 하면 대부분 이것을 사용하게 된다.
compileOnly
컴파일 시점에 꼭 필요한 라이브러리
Lombok 같은 라이브러리가 이에 해당한다.
runtimeOnly
컴파일 시점에는 필요 없지만, 런타임에 필요한 라이브러리
Logging 관련 라이브러리, DB 관련 라이브러리 등이 있겠다.
Reference
https://docs.gradle.org/current/userguide/java_library_plugin.html
https://www.geeksforgeeks.org/how-is-compiletime-classpath-different-from-runtime-classpath-in-java/
https://tomgregory.com/gradle-implementation-vs-compile-dependencies/
https://stackoverflow.com/questions/4270950/compile-time-vs-run-time-dependency-java/4271013
https://stackoverflow.com/questions/44493378/whats-the-difference-between-implementation-and-compile-in-gradle
'Computer Science > Etc' 카테고리의 다른 글
NGINX(엔진엑스) 명령어 및 옵션 정리 (0) | 2023.02.12 |
---|---|
RAID(레이드)란 무엇인가? (0) | 2022.01.31 |
GitHub에서의 Git 토큰 인증 (1) | 2021.09.22 |
M1 맥북에서 MySQL 설치하기 (7) | 2021.03.15 |
MySQL에서 sql 파일로 데이터 추가 시 한글 깨짐 문제(feat:명령프롬프트) (0) | 2020.11.02 |