
SpringBoot 프로젝트에서 의존성을 설정할 때, build.gradle 파일에서 다양한 의존성을 정의한다. 의존성을 설정하기 위해 검색을 하다 보면 implementation를 통해 의존성을 설정하는 경우도 있고, runtimeOnly를 사용하는 예시도 자주보게 된다.
Gradle의 공식문서에 따르면, Java 라이브러리 플러그인을 사용할 때의 구성이 어떻게 설정되는지 아래와 같이 나타낸다.
우선 implementation, runtimeOnly, compileOnly, api, compileOnlyApi 는 Gradle에서 의존성을 관리할 때 사용하는 configuration이다.
각 configuration은 의존성의 사용 목적과 라이프 사이클에 따라 구분되며, 이를 적절히 구분해서 사용하는 것은 프로젝트의 의존성 관리를 효율적으로 하고, 빌드 성능을 최적화하는 데 도움이 된다고 한다.
1. implementation와 apiimplementation과 api는 컴파일과 실행시 모두 필요한 라이브러리에 사용되며, 둘의 차이점은 외부 프로젝트의 의존성 전파 유무에 있다.
implementation은 의존성이 프로젝트 내부에서만 필요하고, 외부에 노출되지 않아도 될 때 사용하는 반면, api는 프로젝트 내 의존성이 외부에 노출되어야 할 때(Public 메서드와 필드, 상속 등 외부에서 직접 의존성을 사용해야 하는 경우)에 사용된다.
예시) implementation이 적합한 경우private void doSomethingWithLibraryA() {
LibraryAType obj = new LibraryAType();
obj.doSomething();
}
// LibraryAType은 프로젝트 내부에서만 사용되므로, 다른 모듈에서는 LibraryAType이 의존 될 필요가 없다.
예시) api가 적합한 경우public List<LibraryBType> getLibraryAObjects() {
return new ArrayList<>();
}
/* LibraryBType이 public 메서드의 반환 타입으로 노출되어
프로젝트를 사용하는 다른 모듈에서도 LibraryBType에 의존해야 한다. */
📌 핵심 요약
api로 의존성이 노출되면 외부 모듈에서 이를 사용하게 되어 의존성 그래프가 복잡해지고, 컴파일 시 더 많은 클래스패스를 관리해야 한다. 이는 불필요한 리컴파일과 빌드 시간 증가를 초래할 수 있다.
반면,implementation은 의존성을 프로젝트 내에서만 사용하도록 제한하여 더 작은 클래스패스를 유지하고, 불필요한 의존성 검사를 줄여 빌드 시간을 단축시킨다.
따라서 Gradle은api보단implementation사용을 권장하며, 외부에 노출될 필요가 없는 의존성에는implementation을 사용하는 것이 효율적이다.
2. runtimeOnly컴파일 시에는 필요없고, 실행 시에만 필요한 라이브러리를 정의한다. 예를 들어, 데이터베이스 드라이버나 로그 라이브러리처럼 애플리케이션 실행에만 필요한 의존성을 설정할 때 사용된다.
3. compileOnly와 compileOnlyApi컴파일 시에는 필요하지만, 실행 시에는 포함되지 않는 라이브러리를 정의한다. 예를 들어, 어노테이션 처리기나 플러그인 의존성을 설정할 때 사용된다. compileOnly와 compileOnlyApi 또한 의존성 전파 유무의 차이가 있으며, compileOnlyApi는 다른 모듈에서도 컴파일 시 필요하지만, 런타임에는 필요하지 않는 경우에 사용된다.
이번 글을 통해 Gradle에서의 의존성 관리 설정인implementation, api, runtimeOnly, compileOnly, compileOnlyApi를 알아보았다. 이를 적절히 활용하면 의존성 관리 효율성 뿐만 아니라 빌드 성능을 최적화할 수 있다. 다음엔 기존 프로젝트에 적용하여 빌드 성능 향상 정도를 확인해 보고, 이를 바탕으로 게시글을 작성 해보고자 한다 🧚♀️
Ref.