1. 개요
이 사용방법(예제)에서는 Gradle 프로젝트에서 조건부 의존성을 구성하는 방법을 살펴봅니다.
2. 프로젝트 설정
데모를 위해 다중 모듈 프로젝트를 설정할 것입니다. start.spring.io 로 가서 루트 프로젝트 conditional-dependency-demo를 생성해 봅시다 . 우리는 Spring Boot와 함께 Gradle과 Java를 사용할 것입니다.
또한 두 개의 Provider 모듈인 provider1 및 provider2 와 두 개의 소비자 모듈인 consumer1 및 consumer2 를 추가해 보겠습니다 .
3. 조건부 의존성 구성
프로젝트 속성을 기반으로 두 Provider 모듈 중 하나를 포함하려고 한다고 가정해 보겠습니다. consumer1 모듈 의 경우 isLocal 속성이 지정된 경우 provider1 모듈을 포함하려고 합니다 . 그렇지 않으면 provider2 모듈이 포함되어야 합니다.
이를 위해 consumer1 모듈 의 gradle.settings.kts 파일 에 다음을 추가해 보겠습니다 .
plugins {
id("java")
}
group = "com.baeldung.gradle"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.7.0")
if (project.hasProperty("isLocal")) {
implementation("com.baeldung.gradle:provider1")
} else {
implementation("com.baeldung.gradle:provider2")
}
}
tasks.getByName<Test>("test") {
useJUnitPlatform()
}
이제 의존성 작업을 실행하여 어떤 Provider 모듈이 선택되는지 확인합니다.
gradle -PisLocal dependencies --configuration implementation
> Task :consumer1:dependencies
------------------------------------------------------------
Project ':consumer1'
------------------------------------------------------------
implementation - Implementation only dependencies for source set 'main'. (n)
\--- com.baeldung.gradle:provider1 (n)
(n) - Not resolved (configuration is not meant to be resolved)
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 591ms
1 actionable task: 1 executed
보시다시피 속성을 전달하면 provider1 모듈이 포함됩니다. 이제 속성을 지정하지 않고 의존성 작업을 실행해 보겠습니다.
gradle dependencies --configuration implementation
> Task :consumer1:dependencies
------------------------------------------------------------
Project ':consumer1'
------------------------------------------------------------
implementation - Implementation only dependencies for source set 'main'. (n)
\--- com.baeldung.gradle:provider2 (n)
(n) - Not resolved (configuration is not meant to be resolved)
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 649ms
1 actionable task: 1 executed
보시 다시피 이제 provider2 가 포함됩니다.
4. 모듈 대체를 통한 조건부 의존성 구성
의존성 대체를 통해 의존성을 조건부로 구성하는 다른 접근 방식을 살펴보겠습니다. consumer2 모듈 의 경우 isLocal 속성이 지정된 경우 provider2 모듈을 포함하려고 합니다 . 그렇지 않으면 모듈 provider1을 사용해야 합니다.
이 목표를 달성하기 위해 다음 구성을 consumer2 모듈 에 추가해 보겠습니다 .
plugins {
id("java")
}
group = "com.baeldung.gradle"
version = "0.0.1-SNAPSHOT"
repositories {
mavenCentral()
}
configurations.all {
resolutionStrategy.dependencySubstitution {
if (project.hasProperty("isLocal"))
substitute(project("com.baeldung.gradle:provider1"))
.using(project(":provider2"))
.because("Project property override(isLocal).")
}
}
dependencies {
implementation(project(":provider1"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0")
}
tasks.getByName<Test>("test") {
useJUnitPlatform()
}
이제 동일한 명령을 다시 실행하면 비슷한 결과를 얻을 수 있습니다. 먼저 isLocal 속성을 지정 하여 실행해 보겠습니다 .
gradle -PisLocal dependencies --configuration compilePath
> Task :consumer2:dependencies
------------------------------------------------------------
Project ':consumer2'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
\--- project :provider1 -> project :provider2
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
그리고 당연히 provider1 프로젝트가 provider2 프로젝트 로 대체되는 것을 볼 수 있습니다 . 이제 속성을 지정하지 않고 시도해 보겠습니다.
gradle dependencies --configuration compilePath
> Task :consumer2:dependencies
------------------------------------------------------------
Project ':consumer2'
------------------------------------------------------------
compileClasspath - Compile classpath for source set 'main'.
\--- project :provider1
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 623ms
1 actionable task: 1 executed
예상대로 이번에는 대체가 발생하지 않았고 provider1이 포함되었습니다.
5. 두 접근 방식의 차이점
위의 데모에서 보았듯이 두 접근 방식 모두 의존성을 조건부로 구성한다는 목표를 달성하는 데 도움이 되었습니다. 두 접근 방식의 몇 가지 차이점에 대해 이야기해 보겠습니다.
첫째, 조건부 논리를 직접 작성하는 것은 두 번째 접근 방식에 비해 적은 구성으로 더 간단해 보입니다.
둘째, 두 번째 접근 방식에는 더 많은 구성이 포함되지만 더 관용적으로 보입니다. 두 번째 접근 방식에서는 Gradle 자체에서 제공하는 대체 메커니즘을 사용합니다. 또한 교체 이유도 지정할 수 있습니다. 또한 로그에서 이러한 정보를 사용할 수 없는 첫 번째 접근 방식과 달리 대체가 발생하는 것을 확인할 수 있습니다.
compileClasspath - Compile classpath for source set 'main'.
\--- project :provider1 -> project :provider2
또한 첫 번째 접근 방식에서는 의존성 해결이 필요하지 않았다는 점에 유의하십시오. 다음을 통해 결과를 얻을 수 있습니다.
gradle -PisLocal dependencies --configuration implementation
두 번째 접근 방식에서는 구현 구성을 확인하는 경우 예상한 결과를 볼 수 없습니다. 그 이유는 의존성 해결이 발생할 때만 작동하기 때문입니다. 따라서 다음과 같이 compilePath 구성 에서 사용할 수 있습니다 .
gradle -PisLocal dependencies --configuration compilePath
6. 결론
이것으로 이 글을 마칠 수 있다. 이 기사에서는 Gradle에서 의존성을 조건부로 구성하는 두 가지 접근 방식을 살펴보았습니다. 우리는 또한 둘 사이의 차이점을 분석했습니다.
Gradle과 함께 제공되는 의존성 대체 구성은 보다 관용적인 접근 방식인 것으로 보입니다. 항상 그렇듯이 전체 코드 및 Gradle 구성은 GitHub에서 사용할 수 있습니다 .