如何在Gradle中跨独立项目使用父项目进行依赖与属性管理?
Hey there! I totally get where you're coming from—Maven's parent POM pattern is super intuitive, and it takes a minute to map that to Gradle's way of doing things. The good news is Gradle absolutely supports this scenario, though the terminology is a bit different. Let's break down two common approaches for your use case:
Option 1: Use a Gradle Platform (BOM) for Dependency Version Management
This is the closest equivalent to Maven's dependencyManagement section in a parent POM. It lets you centralize dependency versions and share them across independent projects without tying them into a submodule hierarchy.
Step 1: Create and Publish the Platform Project
Start by making a standalone Gradle project that uses the java-platform plugin. This project will define your shared dependency versions and properties, then publish to a repository (local or remote) so other projects can reference it.
Here's a sample build.gradle for the platform:
plugins { id 'java-platform' id 'maven-publish' // Required to publish the platform for other projects to use } // Define shared properties that other projects can reference ext { springVersion = '6.1.2' junitVersion = '5.10.1' jacksonVersion = '2.15.3' } javaPlatform { allowDependencies() // Uncomment if you want to include direct dependencies, not just version constraints } dependencies { // Define version constraints: other projects inherit these versions when declaring dependencies constraints { api "org.springframework:spring-core:${springVersion}" api "org.springframework:spring-context:${springVersion}" api "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" api "org.junit.jupiter:junit-jupiter-api:${junitVersion}" runtimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}" } } // Configure publishing to a repository (local for testing, remote for team use) publishing { publications { maven(MavenPublication) { from components.javaPlatform } } repositories { mavenLocal() // Publish to your local Maven repo first for testing // Replace with your company's remote repo or Maven Central later // maven { // url = uri("https://your-company-repo.com/maven") // credentials { // username = project.findProperty('repoUsername') ?: System.getenv('REPO_USERNAME') // password = project.findProperty('repoPassword') ?: System.getenv('REPO_PASSWORD') // } // } } }
Run ./gradlew publish to push the platform to your local repository.
Step 2: Reference the Platform in an Independent Project
In any other standalone Gradle project, you can now import the platform to inherit all your centralized dependency versions:
plugins { id 'java' id 'maven-publish' } repositories { mavenLocal() // Match the repo where you published the platform mavenCentral() } dependencies { // Import the platform to inherit version constraints implementation platform('com.yourcompany:shared-platform:1.0.0') // Declare dependencies WITHOUT version numbers—they'll use the platform's versions implementation 'org.springframework:spring-core' implementation 'org.springframework:spring-context' implementation 'com.fasterxml.jackson.core:jackson-databind' testImplementation 'org.junit.jupiter:junit-jupiter-api' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' } test { useJUnitPlatform() }
Option 2: Share Full Build Logic with a Custom Convention Plugin
If you need to share more than just dependency versions—like plugin configurations, Java toolchain settings, test task defaults, or custom tasks—use a Gradle convention plugin. This is like a supercharged version of a Maven parent POM's <build> section.
Step 1: Create and Publish the Convention Plugin
Make another standalone Gradle project, this time using the java-gradle-plugin to build your custom plugin.
Sample build.gradle for the plugin project:
plugins { id 'java-gradle-plugin' id 'maven-publish' } // Define the plugin ID and implementation class gradlePlugin { plugins { javaConventions { id = 'com.yourcompany.java-conventions' implementationClass = 'com.yourcompany.JavaConventionsPlugin' } } } // Shared properties for the plugin to use ext { springVersion = '6.1.2' junitVersion = '5.10.1' javaVersion = 17 } dependencies { implementation gradleApi() // Required to use Gradle's API in the plugin implementation localGroovy() } publishing { publications { maven(MavenPublication) { from components.java } } repositories { mavenLocal() } }
Next, create the plugin implementation class at src/main/groovy/com/yourcompany/JavaConventionsPlugin.groovy:
package com.yourcompany import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.tasks.testing.Test import org.gradle.jvm.toolchain.JavaLanguageVersion class JavaConventionsPlugin implements Plugin<Project> { void apply(Project project) { // Apply base plugins to the target project project.plugins.apply('java') project.plugins.apply('maven-publish') // Configure shared repositories project.repositories { mavenLocal() mavenCentral() } // Configure Java toolchain (enforce consistent Java version across projects) def javaExtension = project.extensions.getByType(JavaPluginExtension) javaExtension.toolchain { languageVersion = JavaLanguageVersion.of(project.ext.javaVersion) } // Add shared dependencies (using the plugin's properties) def springVersion = project.ext.springVersion def junitVersion = project.ext.junitVersion project.dependencies { implementation platform("org.springframework:spring-boot-dependencies:${springVersion}") testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}" } // Configure default test settings project.tasks.named('test', Test) { useJUnitPlatform() testLogging { events 'PASSED', 'FAILED', 'SKIPPED' } } } }
Run ./gradlew publish to push the plugin to your local repository.
Step 2: Use the Convention Plugin in an Independent Project
Now any standalone project can apply your plugin to inherit all the shared build logic:
plugins { id 'com.yourcompany.java-conventions' version '1.0.0' } // Add project-specific dependencies (no version numbers needed!) dependencies { implementation 'org.springframework:spring-core' implementation 'org.springframework:spring-context' }
Key Takeaways
- For dependency version management only, use a Gradle Platform (BOM)—it's the direct equivalent of Maven's
dependencyManagement. - For full build logic sharing (plugins, tasks, toolchains), use a Convention Plugin—this goes beyond what a Maven parent POM can do.
Both approaches let you keep your projects independent (no submodule ties) while centralizing shared configuration.
内容的提问来源于stack exchange,提问作者carlspring

