Gradle manages dependencies through configurations — similar to Maven scopes but more flexible.

Declaring Dependencies

  dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web:3.2.0")
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
    runtimeOnly("com.mysql:mysql-connector-j:8.2.0")
    compileOnly("org.projectlombok:lombok:1.18.30")
    annotationProcessor("org.projectlombok:lombok:1.18.30")
}
  

Configurations

Configuration Purpose Maven Equivalent
implementation Compile + runtime, not exposed compile
api Compile + runtime, exposed to consumers compile
compileOnly Compile only, not in output provided
runtimeOnly Runtime only runtime
testImplementation Test compile + runtime test
testRuntimeOnly Test runtime only test
annotationProcessor Annotation processing provided

Use implementation by default. Use api only when types are part of your public API.

Repositories

  repositories {
    mavenCentral()
    maven { url = uri("https://repo.spring.io/milestone") }
    mavenLocal()
}
  

Dependency Constraints (BOM)

Import a BOM to manage versions:

  dependencies {
    implementation(platform("org.springframework.boot:spring-boot-dependencies:3.2.0"))
    implementation("org.springframework.boot:spring-boot-starter-web") // no version
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
}
  

Version Catalogs

Centralize versions in gradle/libs.versions.toml:

  [versions]
spring-boot = "3.2.0"
junit = "5.10.0"

[libraries]
spring-web = { module = "org.springframework.boot:spring-boot-starter-web" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }

[plugins]
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
  

build.gradle.kts:

  dependencies {
    implementation(libs.spring.web)
    testImplementation(libs.junit.jupiter)
}
  

Excluding Transitive Dependencies

  dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web") {
        exclude(group = "org.springframework.boot", module = "spring-boot-starter-tomcat")
    }
}
  

Viewing Dependencies

  ./gradlew dependencies
./gradlew :app:dependencies --configuration compileClasspath
./gradlew dependencyInsight --dependency guava
  

Resolution Strategy

Force a specific version:

  configurations.all {
    resolutionStrategy {
        force("com.google.guava:guava:33.0.0-jre")
    }
}
  

Best Practices

  • Use Version Catalogs for multi-module projects
  • Prefer implementation over api to reduce classpath leakage
  • Import BOMs for framework ecosystems (Spring Boot, Micronaut)
  • Run ./gradlew dependencies to diagnose conflicts
  • Use compileOnly + annotationProcessor for Lombok and MapStruct