This document describes the architecture of the Spring Framework's Gradle-based multi-project build system. It focuses on how the root build configuration files orchestrate compilation, testing, and publishing across 20+ Spring modules through consistent conventions and dependency management.
The build system consists of:
buildSrc/ containing ConventionsPlugin, JavaConventions, KotlinConventions, etc.For custom build conventions and plugins implemented in buildSrc/, see Build Conventions and Plugins. For the Bill of Materials (BOM) and dependency version constraints, see Dependency Management and BOM. For multi-release JAR support, see Multi-Release JAR Support.
The Spring Framework uses a multi-project Gradle build with 20+ modules. The build system applies consistent conventions across all modules while allowing for module-specific customization.
Sources: build.gradle1-89 settings.gradle1-53 gradle.properties1-12
The root build.gradle file orchestrates the entire build by:
framework-platformSources: build.gradle1-10
The root build script declares plugins with apply false, making them available to subprojects without applying them to the root project itself. Individual modules apply these plugins as needed.
The build distinguishes between two types of projects:
| Extension Property | Definition | Count | Purpose |
|---|---|---|---|
moduleProjects | subprojects.findAll { it.name.startsWith("spring-") } | ~20 | Spring Framework modules that produce artifacts |
javaProjects | subprojects.findAll { !it.name.startsWith("framework-") } | All except framework-* | Projects that compile Java code |
Sources: build.gradle12-15
All projects in the build configure repositories based on the project version:
Sources: build.gradle19-37 gradle.properties1
The version string 7.0.5-SNAPSHOT triggers both milestone and snapshot repository inclusion. Snapshot dependencies are not cached (cacheChangingModulesFor 0, "seconds").
The settings.gradle file defines all modules included in the build using include statements.
Sources: settings.gradle5-31
Each module maps to a subdirectory with a matching name. The build script convention sets buildFileName = "${project.name}.gradle" for each project.
The build configures Develocity build scans to capture build URI:
Sources: settings.gradle38-52
When a build scan is published, the URI is written to build/build-scan-uri.txt for CI systems to consume.
All projects except framework-platform participate in centralized dependency management:
Sources: build.gradle39-51
The dependencyManagement configuration:
canBeConsumed = false and canBeResolved = falseframework-platform enforced platformThis ensures version alignment across all modules without requiring explicit version declarations.
The root build applies different configurations to different project groups:
Applied to allprojects (including root):
org.springframework.build.localdev plugin"org.springframework"Sources: build.gradle19-37
Applied to [rootProject] + javaProjects:
java pluginjava-test-fixtures pluginorg.springframework.build.conventions plugingradle/ide.gradleSources: build.gradle53-84
Common test dependencies include:
| Dependency | Configuration | Purpose |
|---|---|---|
org.junit.jupiter:junit-jupiter | testImplementation | JUnit 5 API |
org.junit.platform:junit-platform-suite | testImplementation | Test suite support |
org.mockito:mockito-core | testImplementation | Mocking framework |
io.mockk:mockk | testImplementation | Kotlin mocking |
org.assertj:assertj-core | testImplementation | Fluent assertions |
org.apache.logging.log4j:log4j-core | testRuntimeOnly | Test logging |
Applied to moduleProjects (spring-* modules):
gradle/spring-module.gradleSources: build.gradle86-88
The gradle.properties file defines build-wide properties:
| Property | Value | Purpose |
|---|---|---|
version | 7.0.5-SNAPSHOT | Framework version |
org.gradle.caching | true | Enable build cache |
org.gradle.jvmargs | -Xmx2048m | Gradle daemon heap size |
org.gradle.parallel | true | Enable parallel execution |
kotlinVersion | 2.2.21 | Kotlin compiler version |
byteBuddyVersion | 1.17.6 | ByteBuddy agent version (used by TestConventions) |
Sources: gradle.properties1-12
The byteBuddyVersion property is used by buildSrc/src/main/java/org/springframework/build/TestConventions.java84-94 to configure the ByteBuddy agent on test tasks via the -javaagent JVM argument for runtime bytecode manipulation during testing.
The project uses Gradle Wrapper to ensure consistent Gradle versions across development environments and CI builds.
Gradle Wrapper Configuration
| File | Purpose |
|---|---|
gradlew / gradlew.bat | Shell/batch scripts that download and execute Gradle |
| gradle/wrapper/gradle-wrapper.properties1-7 | Wrapper configuration |
| gradle/wrapper/gradle-wrapper.jar | Bootstrap JAR for downloading Gradle |
Sources: gradle/wrapper/gradle-wrapper.properties1-7 gradlew1-249 gradlew.bat1-94
The wrapper uses Gradle 9.3.1 (specified via distributionUrl) and validates the distribution checksum for security.
Build Phase Execution Order
Sources: gradle/wrapper/gradle-wrapper.properties3 build.gradle1-89 settings.gradle1-53 buildSrc/src/main/java/org/springframework/build/ConventionsPlugin.java20-47 buildSrc/src/main/java/org/springframework/build/JavaConventions.java48-54
The ConventionsPlugin serves as the central orchestrator, applying JavaConventions, KotlinConventions, TestConventions, and CheckstyleConventions to projects with the JavaBasePlugin. Each convention class configures specific aspects of the build (toolchains, compiler arguments, test framework, code style).
Each spring-* module follows a consistent structure:
Sources: spring-core/spring-core.gradle1-171 spring-web/spring-web.gradle1-106 spring-test/spring-test.gradle1-120
The spring-test module demonstrates typical dependency patterns:
project(":spring-core") - exposed to consumersSources: spring-test/spring-test.gradle5-94
The root build defines external Javadoc links for cross-referencing:
Sources: build.gradle70-83
These links are used by Javadoc and Dokka tasks to generate hyperlinks to external API documentation.
Refresh this wiki