乐闻世界logo
搜索文章和话题

How does Gradle implement multi-project builds? How to configure dependencies between projects?

2月21日 18:10

Gradle's multi-project build feature allows developers to manage multiple related projects in a single build, which is very useful for large applications and microservice architectures. Here's a detailed explanation of Gradle multi-project builds:

Multi-Project Build Structure

Basic Directory Structure

shell
my-project/ ├── settings.gradle ├── build.gradle ├── app/ │ ├── build.gradle │ └── src/ ├── library/ │ ├── build.gradle │ └── src/ └── common/ ├── build.gradle └── src/

settings.gradle Configuration

groovy
// settings.gradle rootProject.name = 'my-project' // Include subprojects include 'app', 'library', 'common' // Include projects using relative paths include ':data:repository' project(':data:repository').projectDir = new File(rootDir, 'modules/data/repository') // Exclude project // include 'excluded-module'

Project Configuration

Root Project Configuration

groovy
// build.gradle (root project) allprojects { group = 'com.example' version = '1.0.0' repositories { mavenCentral() } } subprojects { apply plugin: 'java' java { sourceCompatibility = JavaVersion.VERSION_17 } dependencies { implementation 'org.slf4j:slf4j-api:2.0.7' } }

Specific Project Configuration

groovy
// app/build.gradle dependencies { implementation project(':library') implementation project(':common') testImplementation project(':common').sourceSets.test.output } // library/build.gradle dependencies { api project(':common') }

Project Dependencies

Inter-Project Dependencies

groovy
// Using project() method dependencies { implementation project(':library') testImplementation project(':common').sourceSets.test.output // Using configuration implementation project(path: ':library', configuration: 'runtimeClasspath') }

Dependency Configuration

groovy
// Define configuration in dependent project // library/build.gradle configurations { apiElements { canBeResolved = false canBeConsumed = true attributes { attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, 'java-api')) } } } // Use in dependent project // app/build.gradle dependencies { implementation project(path: ':library', configuration: 'apiElements') }

Project Properties and Configuration

Project Properties

groovy
// Define project properties ext { springBootVersion = '3.0.0' junitVersion = '5.9.0' } // Access in subprojects // app/build.gradle dependencies { implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" }

Conditional Configuration

groovy
// Configure based on project name configure(subprojects.findAll { it.name.startsWith('web-') }) { apply plugin: 'war' } // Configure based on project properties subprojects { if (project.hasProperty('enableJacoco')) { apply plugin: 'jacoco' } }

Shared Configuration

Using Configuration Injection

groovy
// build.gradle (root project) subprojects { // Configure all subprojects apply plugin: 'java' // Configure Java compilation tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs << '-Xlint:unchecked' } // Configure tests test { useJUnitPlatform() testLogging { events 'passed', 'skipped', 'failed' } } }

Using Convention Plugins

groovy
// buildSrc/src/main/groovy/JavaLibraryPlugin.groovy class JavaLibraryPlugin implements Plugin<Project> { void apply(Project project) { project.with { apply plugin: 'java-library' java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } dependencies { api platform('org.springframework.boot:spring-boot-dependencies:3.0.0') } } } } // Use in subprojects // library/build.gradle plugins { id 'java-library-convention' }

Build Tasks

Run Tasks Across All Projects

bash
# Run clean task in all projects ./gradlew clean # Run test task in all projects ./gradlew test # Run tasks for specific project ./gradlew :app:build ./gradlew :library:test

Task Dependencies

groovy
// app/build.gradle tasks.named('build') { dependsOn ':library:build', ':common:build' } // Root project build.gradle tasks.register('buildAll') { dependsOn subprojects.collect { "${it.path}:build" } }

Multi-Project Build Best Practices

1. Reasonable Project Division

groovy
// Divide by functional modules include 'core', 'api', 'web', 'data', 'service' // Divide by layers include 'common', 'infrastructure', 'domain', 'application'

2. Shared Dependency Management

groovy
// build.gradle (root project) ext { versions = [ springBoot: '3.0.0', junit: '5.9.0', mockito: '5.0.0' ] libs = [ springBootWeb: "org.springframework.boot:spring-boot-starter-web:${versions.springBoot}", junit: "org.junit.jupiter:junit-jupiter:${versions.junit}", mockito: "org.mockito:mockito-core:${versions.mockito}" ] } // Use in subprojects // app/build.gradle dependencies { implementation libs.springBootWeb testImplementation libs.junit testImplementation libs.mockito }

3. Use Version Catalog

groovy
// gradle/libs.versions.toml [versions] spring-boot = "3.0.0" junit = "5.9.0" [libraries] spring-boot-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring-boot" } jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } [plugins] java = { id = "java" } spring-boot = { id = "org.springframework.boot", version = "3.0.0" } // Use in subprojects // app/build.gradle plugins { id libs.plugins.java.get().pluginId } dependencies { implementation libs.spring.boot.web testImplementation libs.jupiter }

4. Avoid Circular Dependencies

groovy
// Check for circular dependencies ./gradlew :app:dependencies --configuration runtimeClasspath // Use dependency analysis tools plugins { id 'com.github.dependency-license-report' version '2.5' }

Performance Optimization

Parallel Build

groovy
// gradle.properties org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true

Configuration Optimization

groovy
// Use lazy configuration subprojects { tasks.register('customTask') { // Task is only created when needed } } // Avoid time-consuming operations in configuration phase subprojects { // Don't perform network requests or file I/O here }

Common Commands

bash
# View project structure ./gradlew projects # View all tasks ./gradlew tasks # View tasks for specific project ./gradlew :app:tasks # View project dependencies ./gradlew :app:dependencies # Build all projects ./gradlew build # Build specific project ./gradlew :app:build # Clean all projects ./gradlew clean # Parallel build ./gradlew build --parallel
标签:Gradle