Gradle을 쓰다 보면 implementation
, compileOnly
, runtimeOnly
같은 키워드가 반복된다.
처음에는 무작정 복붙하지만, 프로젝트가 커질수록 "왜 이게 들어가 있지?" 하는 의문이 들기 마련이다.
이 포스트에서는 각 스코프가 언제, 어디서, 왜 사용되는지를 표와 함께 정리해봤다.
의존성 스코프는 말 그대로 라이브러리를 언제(컴파일, 런타임, 테스트) 사용할지 정의하는 역할을 한다.
이를 통해 불필요한 라이브러리 포함을 방지하고, 빌드 시간과 실행 크기를 줄일 수 있다.
스코프 | 컴파일 | 런타임 | 테스트 전용 | 용도 |
---|---|---|---|---|
compileOnly | ✅ | ❌ | ❌ | 컴파일 시점에만 필요 (ex. lombok) |
implementation | ✅ | ✅ | ❌ | 주로 사용하는 기본 의존성 |
runtimeOnly | ❌ | ✅ | ❌ | 실행 시에만 필요한 라이브러리 (ex. JDBC driver) |
testCompileOnly | ✅ | ❌ | ✅ | 테스트에서만 컴파일 필요 |
testImplementation | ✅ | ✅ | ✅ | 테스트에서만 컴파일 + 실행 |
testRuntimeOnly | ❌ | ✅ | ✅ | 테스트에서 실행 시에만 필요 |
annotationProcessor | ✅ | ❌ | ❌ | 애노테이션 처리기 등록 |
compileClasspath , runtimeClasspath | ✅ / ❌ | ❌ / ✅ | ❌ | 커스텀 빌드 구성 시 사용 |
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.mockito:mockito-core'
Gradle 의존성 스코프를 제대로 활용하면 다음과 같은 이점이 있다:
💡 Tip: build.gradle에 의존성을 추가할 땐 "이게 정말 런타임에 필요할까?"를 한 번쯤 자문해보자. 성능과 유지보수에 큰 차이를 만든다.