📌 第一阶段:Gradle 基础概念与环境搭建 🎯 1. Gradle 是什么?深度解析 1.1 Gradle 的核心优势 Gradle是一个开源的构建自动化工具,专注于灵活性和性能。它结合了Ant的强大功能和Maven的依赖管理概念。
🔧 五大核心优势:
高性能 :增量构建、构建缓存、并行执行
灵活性 :基于Groovy/Kotlin DSL的强大脚本能力
可扩展性 :丰富的插件生态系统
多语言支持 :Java、Kotlin、Scala、C++、Python等
企业级特性 :构建扫描、依赖洞察、性能分析
1.2 Gradle vs. Maven vs. Ant 详细对比
特性
Gradle
Maven
Ant
配置语言
Groovy/Kotlin DSL
XML
XML
构建性能
🥇 最快(增量构建+缓存)
🥉 较慢
🥈 中等
灵活性
🥇 极高(编程式配置)
🥉 较低(约定优于配置)
🥈 高(过程式)
学习曲线
🥈 中等偏陡
🥇 相对简单
🥉 复杂
依赖管理
🥇 强大且灵活
🥈 强大但固化
🥉 需手动管理
多项目支持
🥇 原生支持
🥈 通过聚合
🥉 需手动配置
IDE支持
🥇 优秀
🥇 优秀
🥈 一般
生态系统
🥈 快速发展
🥇 最成熟
🥉 逐渐衰落
企业采用
🥈 快速增长
🥇 最广泛
🥉 逐渐减少
1.3 Gradle 的核心概念 🎯 项目(Project)
每个构建都包含一个或多个项目
项目代表可以构建的组件(如JAR库、Web应用等)
由build.gradle文件定义
🎯 任务(Task)
构建的基本工作单元
如编译代码、运行测试、创建JAR等
任务之间可以有依赖关系
🎯 插件(Plugin)
扩展Gradle功能的模块
提供任务、约定和配置
如Java插件、Spring Boot插件等
🎯 构建脚本(Build Script)
使用Groovy或Kotlin DSL编写
定义项目配置、依赖、任务等
具有强大的编程能力
🛠️ 2. Gradle 安装与配置详解 2.1 安装方式对比 方式1:使用Gradle Wrapper(推荐)
./gradlew build gradlew.bat build
方式2:手动安装
export GRADLE_HOME=/opt/gradle/gradle-8.4export PATH=$PATH :$GRADLE_HOME /bingradle --version
方式3:包管理器安装
brew install gradle sudo apt install gradle choco install gradle scoop install gradle
2.2 Gradle Wrapper 详解 🔧 生成Wrapper
gradle wrapper --gradle-version 8.4 project/ ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── build.gradle
📝 gradle-wrapper.properties配置
distributionBase =GRADLE_USER_HOME distributionPath =wrapper/dists distributionUrl =https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout =10000 zipStoreBase =GRADLE_USER_HOME zipStorePath =wrapper/dists
🚀 Wrapper优化配置
distributionUrl =https\://mirrors.cloud.tencent.com/gradle/gradle-8.4-bin.zip distributionUrl =https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.4-bin.zip networkTimeout =10000 # 网络超时时间(毫秒) validateDistributionUrl =true # 验证下载URL zipStoreBase =GRADLE_USER_HOME # ZIP存储基础目录 zipStorePath =wrapper/dists # ZIP存储路径
💡 Wrapper配置实战案例
distributionUrl=https\://nexus.company.com/repository/gradle-distributions/gradle-8.4-bin.zip ./gradlew wrapper --gradle-version 8.4 --distribution-type bin distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists
2.3 Gradle 配置优化 📁 gradle.properties(项目级配置)详解
org.gradle.daemon =true org.gradle.parallel =true org.gradle.configureondemand =true org.gradle.caching =true org.gradle.jvmargs =-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 systemProp.file.encoding =UTF-8 systemProp.http.proxyHost =proxy.company.com systemProp.http.proxyPort =8080 systemProp.http.proxyUser =username systemProp.http.proxyPassword =password systemProp.https.proxyHost =proxy.company.com systemProp.https.proxyPort =8080 systemProp.https.proxyUser =username systemProp.https.proxyPassword =password systemProp.http.nonProxyHosts =localhost|127.0.0.1|*.company.com org.gradle.console =rich org.gradle.logging.level =lifecycle org.gradle.warning.mode =all version =1.0.0-SNAPSHOT app.name =MyApplication app.description =My Gradle Application app.mainClass =com.example.Application db.url =jdbc:mysql://localhost:3306/myapp db.username =dev_user db.password =dev_password build.timestamp =${new Date().format('yyyy-MM-dd HH:mm:ss')}
🏠 ~/.gradle/gradle.properties(全局配置)详解
org.gradle.jvmargs =-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC org.gradle.parallel =true org.gradle.caching =true org.gradle.daemon =true systemProp.http.proxyHost =proxy.company.com systemProp.http.proxyPort =8080 systemProp.https.proxyHost =proxy.company.com systemProp.https.proxyPort =8080 systemProp.gradle.wrapperUser =username systemProp.gradle.wrapperPassword =password nexusUsername =your_username nexusPassword =your_password signing.keyId =12345678 signing.password =your_signing_password signing.secretKeyRingFile =/Users/username/.gnupg/secring.gpg developer.name =John Doe developer.email =john.doe@company.com developer.organization =My Company org.gradle.console =rich org.gradle.warning.mode =all
💡 全局配置实战案例
案例1:企业开发环境统一配置
org.gradle.jvmargs =-Xmx6g -XX:MaxMetaspaceSize=512m -XX:+UseG1GC systemProp.http.proxyHost =proxy.company.com systemProp.http.proxyPort =8080 systemProp.https.proxyHost =proxy.company.com systemProp.https.proxyPort =8080 systemProp.http.nonProxyHosts =*.company.com|localhost nexusUsername =${env.NEXUS_USERNAME} nexusPassword =${env.NEXUS_PASSWORD} developer.name =${env.USER} developer.email =${env.USER}@company.com
案例2:个人开发机优化配置
org.gradle.jvmargs =-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC -XX:+UseStringDeduplication org.gradle.parallel =true org.gradle.workers.max =8 org.gradle.caching =true org.gradle.configuration-cache =true org.gradle.console =verbose org.gradle.logging.level =info
案例3:CI/CD环境配置
org.gradle.jvmargs =-Xmx4g -XX:MaxMetaspaceSize=512m org.gradle.daemon =false # CI环境不使用守护进程 org.gradle.parallel =true # 启用并行构建 org.gradle.caching =true # 启用构建缓存 org.gradle.console =plain # 纯文本输出 org.gradle.logging.level =info # 详细日志 org.gradle.warning.mode =fail # 警告时失败
📁 3. Gradle 项目结构深度解析 3.1 标准项目结构 my-gradle-project/ ├── build.gradle(.kts) ├── settings.gradle(.kts) ├── gradle.properties ├── gradlew ├── gradlew.bat ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src/ │ ├── main/ │ │ ├── java/ │ │ ├── kotlin/ │ │ ├── resources/ │ │ └── webapp/ │ ├── test / │ │ ├── java/ │ │ ├── kotlin/ │ │ └── resources/ │ └── integrationTest/ ├── build/ │ ├── classes/ │ ├── libs/ │ ├── reports/ │ └── tmp/ └── README.md
3.2 核心文件详解 📋 build.gradle 基础结构
plugins { id 'java' id 'application' id 'org.springframework.boot' version '2.7.0' } group = 'com.example' version = '1.0.0' sourceCompatibility = '11' repositories { mavenCentral() gradlePluginPortal() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.junit.jupiter:junit-jupiter' } tasks.named('test' ) { useJUnitPlatform() } application { mainClass = 'com.example.Application' }
⚙️ settings.gradle 配置
rootProject.name = 'my-gradle-project' include 'subproject1' , 'subproject2' pluginManagement { repositories { gradlePluginPortal() mavenCentral() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenCentral() } }
3.3 创建Gradle项目 方法1:使用Gradle init(推荐)
gradle init --type java-application --dsl groovy --test-framework junit-jupiter gradle init --type java-library --dsl kotlin --test-framework spock gradle init --type java-application --dsl groovy gradle init
方法2:手动创建
mkdir my-gradle-project && cd my-gradle-projectmkdir -p src/main/java/com/examplemkdir -p src/main/resourcesmkdir -p src/test/java/com/examplemkdir -p src/test/resourcestouch build.gradletouch settings.gradletouch gradle.propertiesgradle wrapper --gradle-version 8.4
📝 最小化build.gradle示例
plugins { id 'java' } repositories { mavenCentral() } dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' } tasks.named('test' ) { useJUnitPlatform() }
📌 第二阶段:Gradle DSL 语法与构建脚本 📝 4. Groovy DSL 深度解析 4.1 Groovy DSL 基础语法 🎯 基本语法特性
println 'Hello Gradle' println('Hello Gradle' ) def version = '1.0.0' println "Current version: ${version}" println "Current version: $version" def myClosure = { param -> println "Parameter: $param" } myClosure('test' ) def list = ['java' , 'kotlin' , 'scala' ]list.each { language -> println "Language: $language" } def config = [ version: '1.0.0' , encoding: 'UTF-8' ] println config.version
🔧 Gradle DSL 核心概念
android { compileSdkVersion 33 defaultConfig { applicationId "com.example.app" minSdkVersion 21 } } task myTask { doLast { println 'Executing myTask' } } dependencies { implementation 'org.springframework:spring-core:5.3.21' testImplementation 'junit:junit:4.13.2' } project.version = '1.0.0' version = '1.0.0'
4.2 构建脚本结构详解 📋 完整的build.gradle结构
plugins { id 'java' id 'application' id 'org.springframework.boot' version '2.7.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' if (project.hasProperty('android' )) { id 'com.android.application' } } group = 'com.example' version = '1.0.0-SNAPSHOT' description = 'My Gradle Project' java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 withJavadocJar() withSourcesJar() } repositories { mavenLocal() mavenCentral() gradlePluginPortal() maven { name = 'Aliyun' url = 'https://maven.aliyun.com/repository/public' } maven { name = 'Spring Milestones' url = 'https://repo.spring.io/milestone' mavenContent { includeGroupByRegex 'org\\.springframework.*' includeGroup 'org.springframework.boot' includeGroup 'org.springframework.cloud' } } maven { name = 'CompanyNexus' url = 'https://nexus.company.com/repository/maven-public/' credentials { username = project.findProperty('nexusUsername' ) ?: 'guest' password = project.findProperty('nexusPassword' ) ?: 'guest' } authentication { basic(BasicAuthentication) } } maven { name = 'CompanySnapshots' url = 'https://nexus.company.com/repository/maven-snapshots/' credentials { username = project.findProperty('nexusUsername' ) password = project.findProperty('nexusPassword' ) } mavenContent { snapshotsOnly() } } if (project.hasProperty('useInternalRepo' )) { maven { name = 'InternalRepo' url = 'https://internal.company.com/repository/' } } } repositories { if (project.hasProperty('dev' )) { mavenLocal() maven { url 'https://maven.aliyun.com/repository/public' } mavenCentral() } else { mavenCentral() maven { url 'https://nexus.company.com/repository/maven-public/' credentials { username nexusUsername password nexusPassword } } } } ext { springBootVersion = '2.7.0' junitVersion = '5.9.2' mockitoVersion = '4.11.0' } dependencies { implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' compileOnly 'javax.servlet:javax.servlet-api:4.0.1' compileOnly 'org.projectlombok:lombok:1.18.24' runtimeOnly 'mysql:mysql-connector-java:8.0.33' runtimeOnly 'com.h2database:h2:2.1.214' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' annotationProcessor 'org.projectlombok:lombok:1.18.24' testImplementation "org.junit.jupiter:junit-jupiter:${junitVersion}" testImplementation "org.mockito:mockito-core:${mockitoVersion}" testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.testcontainers:junit-jupiter:1.17.3' testImplementation 'org.testcontainers:mysql:1.17.3' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'mysql:mysql-connector-java' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' implementation 'org.apache.commons:commons-lang3' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.testcontainers:mysql' testRuntimeOnly 'com.h2database:h2' } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' implementation 'org.springframework.cloud:spring-cloud-starter-loadbalancer' implementation 'org.springframework.boot:spring-boot-starter-amqp' implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' } tasks.named('test' ) { useJUnitPlatform() jvmArgs = ['-Xmx1024m' ] systemProperty 'spring.profiles.active' , 'test' reports { html.required = true junitXml.required = true } testLogging { events 'passed' , 'skipped' , 'failed' exceptionFormat = 'full' } } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs += ['-parameters' , '-Xlint:unchecked' ] } jar { manifest { attributes( 'Implementation-Title' : project.name, 'Implementation-Version' : project.version, 'Main-Class' : 'com.example.Application' ) } exclude 'META-INF/*.RSA' , 'META-INF/*.SF' , 'META-INF/*.DSA' } task printProjectInfo { group = 'help' description = '打印项目信息' doLast { println "Project: ${project.name}" println "Version: ${project.version}" println "Java Version: ${java.sourceCompatibility}" println "Dependencies: ${configurations.runtimeClasspath.files.size()}" } } application { mainClass = 'com.example.Application' applicationDefaultJvmArgs = ['-Xmx512m' ] } publishing { publications { maven(MavenPublication) { from components.java pom { name = project.name description = project.description url = 'https://github.com/example/my-project' licenses { license { name = 'Apache License 2.0' url = 'https://www.apache.org/licenses/LICENSE-2.0' } } developers { developer { id = 'johndoe' name = 'John Doe' email = 'john@example.com' } } } } } repositories { maven { name = 'CompanyNexus' url = version.endsWith('SNAPSHOT' ) ? 'https://nexus.company.com/repository/maven-snapshots/' : 'https://nexus.company.com/repository/maven-releases/' credentials { username = project.findProperty('nexusUsername' ) password = project.findProperty('nexusPassword' ) } } } }
4.3 Kotlin DSL 对比 📝 build.gradle.kts 示例
plugins { java application id("org.springframework.boot" ) version "2.7.0" } group = "com.example" version = "1.0.0" java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-web" ) testImplementation("org.junit.jupiter:junit-jupiter:5.9.2" ) } tasks.named<Test>("test" ) { useJUnitPlatform() } application { mainClass.set ("com.example.Application" ) }
🔍 Groovy vs Kotlin DSL 对比
特性
Groovy DSL
Kotlin DSL
语法
动态、简洁
静态类型、严格
IDE支持
基础支持
优秀的代码补全和重构
性能
运行时解析
编译时检查
学习曲线
较平缓
需要Kotlin知识
错误检测
运行时
编译时
重构支持
有限
强大
🔍 5. 依赖管理深度实践 5.1 依赖配置详解 📦 依赖配置类型
配置
说明
编译时
运行时
测试时
传递性
implementation
实现依赖(推荐)
✅
✅
✅
❌
api
API依赖
✅
✅
✅
✅
compileOnly
仅编译时
✅
❌
✅
❌
runtimeOnly
仅运行时
❌
✅
✅
❌
testImplementation
测试实现
❌
❌
✅
❌
testCompileOnly
测试编译时
❌
❌
✅
❌
testRuntimeOnly
测试运行时
❌
❌
✅
❌
🔧 实际应用示例
dependencies { implementation 'org.springframework:spring-core:5.3.21' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' api 'org.apache.commons:commons-lang3:3.12.0' compileOnly 'javax.servlet:javax.servlet-api:4.0.1' compileOnly 'org.projectlombok:lombok:1.18.24' runtimeOnly 'mysql:mysql-connector-java:8.0.33' runtimeOnly 'com.h2database:h2:2.1.214' annotationProcessor 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' }
5.2 版本管理策略 🎯 版本声明方式
dependencies { implementation 'org.springframework:spring-core:5.3.21' implementation "org.springframework:spring-core:${springVersion}" implementation "org.springframework:spring-core:${ext.springVersion}" implementation 'org.springframework:spring-core:5.+' implementation 'org.springframework:spring-core:[5.0,6.0)' implementation 'org.springframework:spring-core:latest.release' } ext { springVersion = '5.3.21' junitVersion = '5.9.2' mockitoVersion = '4.11.0' }
🔧 依赖约束和BOM
dependencies { implementation platform('org.springframework.boot:spring-boot-dependencies:2.7.0' ) implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'com.fasterxml.jackson.core:jackson-core:2.14.0' } dependencyManagement { dependencies { dependency 'org.apache.commons:commons-lang3:3.12.0' dependency 'com.google.guava:guava:31.1-jre' } }
5.3 依赖冲突解决 🔍 查看依赖树
./gradlew dependencies ./gradlew dependencies --configuration runtimeClasspath ./gradlew dependencyInsight --dependency spring-core ./gradlew dependencies --configuration runtimeClasspath | grep "(*)"
🛠️ 解决冲突策略
dependencies { implementation 'org.springframework:spring-core:5.3.21' implementation('org.springframework:spring-context:5.3.21' ) { exclude group: 'commons-logging' , module: 'commons-logging' } implementation('some.group:some-module:1.0' ) { transitive = false } implementation 'commons-logging:commons-logging:1.2' } configurations.all { resolutionStrategy { force 'commons-logging:commons-logging:1.2' failOnVersionConflict() cacheDynamicVersionsFor 10 , 'minutes' cacheChangingModulesFor 4 , 'hours' dependencySubstitution { substitute module('commons-logging:commons-logging' ) with module('org.slf4j:jcl-over-slf4j:1.7.36' ) } } }
📌 第三阶段:Gradle 任务系统与插件 ⚙️ 6. 任务系统深度解析 6.1 任务基础概念 🎯 任务的生命周期
task myTask { println 'Configuring myTask' doFirst { println 'Before myTask execution' } doLast { println 'After myTask execution' } } myTask { description = 'My custom task' group = 'custom' }
🔧 任务类型
task hello { doLast { println 'Hello, Gradle!' } } task copyFiles(type: Copy) { from 'src/main/resources' into 'build/resources' } task createZip(type: Zip) { from 'src/main/java' archiveFileName = 'sources.zip' destinationDirectory = file('build/distributions' ) } class GreetingTask extends DefaultTask { @Input String greeting = 'hello' @Input String recipient = 'world' @TaskAction void greet() { println "${greeting}, ${recipient}!" } } task greeting(type: GreetingTask) { greeting = 'Hi' recipient = 'Gradle' }
6.2 任务依赖与排序 🔗 任务依赖
task taskA { doLast { println 'Task A' } } task taskB { doLast { println 'Task B' } } task taskC { dependsOn taskA, taskB doLast { println 'Task C' } } task taskD { dependsOn tasks.matching { task -> task.name.startsWith('test' ) } doLast { println 'Task D' } } taskC.dependsOn { tasks.findAll { task -> task.name.startsWith('compile' ) && task.enabled } }
📋 任务排序
task taskX { doLast { println 'Task X' } } task taskY { doLast { println 'Task Y' } } taskY.mustRunAfter taskX taskY.shouldRunAfter taskX task cleanup { doLast { println 'Cleanup' } } taskX.finalizedBy cleanup
6.3 任务输入输出 📁 任务输入输出管理详解
task processFiles { inputs.files fileTree('src/main/resources' ) { include '**/*.properties' include '**/*.yml' exclude '**/*.tmp' } inputs.property 'version' , project.version inputs.property 'environment' , project.findProperty('env' ) ?: 'dev' outputs.dir 'build/processed' outputs.cacheIf { true } outputs.upToDateWhen { file('build/processed' ).exists() && file('build/processed' ).lastModified() > inputs.files.asFileTree.maxBy { it.lastModified() }.lastModified() } doLast { outputs.files.singleFile.mkdirs() copy { from inputs.files into outputs.files.singleFile filter { line -> line.replace('${version}' , project.version) .replace('${env}' , project.findProperty('env' ) ?: 'dev' ) } } println "Processed ${inputs.files.files.size()} files to ${outputs.files.singleFile}" } } class ProcessFilesTask extends DefaultTask { @InputFiles @PathSensitive (PathSensitivity.RELATIVE) FileCollection inputFiles @Input String version @Input @Optional String environment = 'dev' @OutputDirectory File outputDir @Internal String logLevel = 'INFO' @TaskAction void processFiles() { outputDir.mkdirs() inputFiles.each { file -> def outputFile = new File(outputDir, file.name) outputFile.text = file.text .replace('${version}' , version) .replace('${environment}' , environment) if (logLevel == 'DEBUG' ) { println "Processed: ${file.name} -> ${outputFile.name}" } } println "Processed ${inputFiles.files.size()} files for environment: ${environment}" } } tasks.register('processConfigFiles' , ProcessFilesTask) { inputFiles = fileTree('src/main/resources/config' ) version = project.version environment = project.findProperty('env' ) ?: 'dev' outputDir = file('build/processed-config' ) } task generateDocumentation { inputs.files fileTree('src/main/java' ) { include '**/*.java' } inputs.files fileTree('docs/templates' ) inputs.property 'version' , project.version inputs.property 'buildTime' , new Date().format('yyyy-MM-dd HH:mm:ss' ) outputs.dir 'build/docs/api' outputs.dir 'build/docs/user-guide' outputs.file 'build/docs/README.html' outputs.cacheIf { project.hasProperty('prod' ) } doLast { exec { commandLine 'javadoc' , '-d' , 'build/docs/api' , '-sourcepath' , 'src/main/java' , '-subpackages' , 'com.example' } copy { from 'docs/templates' into 'build/docs/user-guide' expand( version: project.version, buildTime: new Date().format('yyyy-MM-dd HH:mm:ss' ) ) } def readmeContent = """ # ${project.name} v${project.version} Generated on: ${new Date().format('yyyy-MM-dd HH:mm:ss')} ## API Documentation See [API Docs](api/index.html) ## User Guide See [User Guide](user-guide/index.html) """ .stripIndent() file('build/docs/README.html' ).text = readmeContent } } task copyResources(type: Copy) { from 'src/main/resources' into 'build/resources' filter { line -> line.replace('${project.version}' , project.version) } include '**/*.properties' exclude '**/*.tmp' } task createDistribution(type: Zip) { archiveFileName = "${project.name}-${project.version}.zip" destinationDirectory = file('build/distributions' ) from 'build/libs' from 'src/main/scripts' from 'README.md' } tasks.named('test' ) { inputs.files sourceSets.test.runtimeClasspath inputs.files sourceSets.main.runtimeClasspath inputs.property 'javaVersion' , System.getProperty('java.version' ) outputs.dir 'build/test-results' outputs.dir 'build/reports/tests' outputs.cacheIf { !project.hasProperty('rerunTests' ) } }
🔌 7. 插件系统详解 7.1 插件应用方式 📦 插件应用语法
plugins { id 'java' id 'application' } plugins { id 'org.springframework.boot' version '2.7.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' } apply plugin: 'java' apply plugin: 'application' plugins { id 'java' if (project.hasProperty('android' )) { id 'com.android.application' } } apply from: 'gradle/dependencies.gradle' apply from: 'https://raw.githubusercontent.com/example/scripts/main/common.gradle'
7.2 常用插件详解 ☕ Java插件
plugins { id 'java' } java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 withSourcesJar() withJavadocJar() } compileJava { options.encoding = 'UTF-8' options.compilerArgs += ['-parameters' , '-Xlint:unchecked' ] } test { useJUnitPlatform() testLogging { events 'passed' , 'skipped' , 'failed' } reports { html.required = true junitXml.required = true } }
🌐 Application插件
plugins { id 'application' } application { mainClass = 'com.example.Application' applicationDefaultJvmArgs = ['-Xmx512m' , '-Dfile.encoding=UTF-8' ] }
🌸 Spring Boot插件
plugins { id 'org.springframework.boot' version '2.7.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' } springBoot { buildInfo() mainClass = 'com.example.Application' }
📌 第四阶段:多项目构建与高级特性 🏗️ 8. 多项目构建管理 多项目构建是Gradle的核心优势之一,能够高效管理复杂的企业级项目结构。
8.1 多项目结构设计 📁 典型多项目结构
my-multi-project/ ├── settings.gradle ├── build.gradle ├── gradle.properties ├── gradle/ │ └── wrapper/ ├── buildSrc/ │ ├── build.gradle │ └── src/main/groovy/ ├── common/ │ ├── build.gradle │ └── src/ ├── api/ │ ├── build.gradle │ └── src/ ├── service/ │ ├── build.gradle │ └── src/ ├── web/ │ ├── build.gradle │ └── src/ └── integration-tests/ ├── build.gradle └── src/
8.2 根项目配置 ⚙️ settings.gradle 详细配置
rootProject.name = 'my-multi-project' include 'common' include 'api' include 'service' include 'web' include 'integration-tests' include 'common:common-core' include 'common:common-web' include 'common:common-data' include 'services:user-service' include 'services:order-service' include 'services:payment-service' include 'infrastructure:config-server' include 'infrastructure:eureka-server' project(':common' ).projectDir = file('modules/common' ) project(':api' ).projectDir = file('modules/api' ) ['user-service' , 'order-service' , 'payment-service' ].each { serviceName -> project(":services:${serviceName}" ).projectDir = file("services/${serviceName}" ) } pluginManagement { repositories { gradlePluginPortal() mavenCentral() maven { url = 'https://nexus.company.com/repository/gradle-plugins/' credentials { username = providers.gradleProperty('nexusUsername' ).orNull password = providers.gradleProperty('nexusPassword' ).orNull } } } plugins { id 'org.springframework.boot' version '2.7.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'jacoco' version '0.8.8' id 'com.github.spotbugs' version '5.0.9' id 'checkstyle' version '10.3.1' id 'com.palantir.docker' version '0.34.0' id 'com.google.cloud.tools.jib' version '3.2.1' id 'org.asciidoctor.jvm.convert' version '3.3.2' id 'com.gradle.build-scan' version '3.11' } resolutionStrategy { eachPlugin { if (requested.id.namespace == 'com.company' ) { useModule('com.company:gradle-plugins:1.0.0' ) } } } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { if (providers.gradleProperty('useLocalRepo' ).isPresent()) { mavenLocal() } maven { name = 'CompanyNexus' url = 'https://nexus.company.com/repository/maven-public/' credentials { username = providers.gradleProperty('nexusUsername' ).orNull password = providers.gradleProperty('nexusPassword' ).orNull } } maven { name = 'Aliyun' url = 'https://maven.aliyun.com/repository/public' } mavenCentral() maven { name = 'SpringRepo' url = 'https://repo.spring.io/milestone' mavenContent { includeGroupByRegex 'org\\.springframework.*' } } } versionCatalogs { libs { version('spring-boot' , '2.7.0' ) version('spring-cloud' , '2021.0.3' ) version('junit' , '5.9.2' ) library('spring-boot-starter-web' , 'org.springframework.boot' , 'spring-boot-starter-web' ).versionRef('spring-boot' ) library('spring-boot-starter-test' , 'org.springframework.boot' , 'spring-boot-starter-test' ).versionRef('spring-boot' ) library('junit-jupiter' , 'org.junit.jupiter' , 'junit-jupiter' ).versionRef('junit' ) plugin('spring-boot' , 'org.springframework.boot' ).versionRef('spring-boot' ) plugin('spring-dependency-management' , 'io.spring.dependency-management' ).version('1.0.11.RELEASE' ) bundle('spring-boot-web' , ['spring-boot-starter-web' , 'spring-boot-starter-actuator' ]) bundle('testing' , ['junit-jupiter' , 'spring-boot-starter-test' ]) } } } buildCache { local { enabled = true directory = file('build-cache' ) removeUnusedEntriesAfterDays = 30 } remote(HttpBuildCache) { url = 'https://cache.company.com/' push = providers.gradleProperty('pushToCache' ).isPresent() credentials { username = providers.gradleProperty('cacheUsername' ).orNull password = providers.gradleProperty('cachePassword' ).orNull } } } enableFeaturePreview('TYPESAFE_PROJECT_ACCESSORS' ) enableFeaturePreview('VERSION_CATALOGS' )
💡 settings.gradle配置实战案例
案例1:大型企业项目配置
rootProject.name = 'enterprise-platform' include 'platform-core' include 'platform-common' include 'platform-security' ['user' , 'order' , 'payment' , 'inventory' ].each { module -> include "business-${module}" project(":business-${module}" ).projectDir = file("business/${module}" ) } ['gateway' , 'config' , 'registry' , 'monitor' ].each { infra -> include "infra-${infra}" project(":infra-${infra}" ).projectDir = file("infrastructure/${infra}" ) } pluginManagement { repositories { maven { url = 'https://nexus.corp.com/repository/gradle-plugins/' credentials { username = System.getenv('CORP_NEXUS_USER' ) password = System.getenv('CORP_NEXUS_PASS' ) } } gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url = 'https://nexus.corp.com/repository/maven-public/' credentials { username = System.getenv('CORP_NEXUS_USER' ) password = System.getenv('CORP_NEXUS_PASS' ) } } mavenCentral() } }
案例2:开源项目配置
rootProject.name = 'awesome-library' include 'core' include 'extensions' include 'examples' include 'benchmarks' pluginManagement { repositories { gradlePluginPortal() mavenCentral() } plugins { id 'java-library' id 'maven-publish' id 'signing' id 'org.gradle.test-retry' version '1.4.1' id 'com.gradle.plugin-publish' version '1.0.0' } } dependencyResolutionManagement { repositories { mavenCentral() maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' mavenContent { snapshotsOnly() } } } }
📋 根项目 build.gradle
allprojects { group = 'com.example' version = '1.0.0-SNAPSHOT' repositories { mavenCentral() } } subprojects { apply plugin: 'java' apply plugin: 'java-library' java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } dependencies { implementation 'org.slf4j:slf4j-api:1.7.36' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs += ['-parameters' ] } test { useJUnitPlatform() testLogging { events 'passed' , 'skipped' , 'failed' } } } project(':web' ) { apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' dependencies { implementation project(':service' ) implementation 'org.springframework.boot:spring-boot-starter-web' } } project(':service' ) { dependencies { implementation project(':api' ) implementation project(':common' ) implementation 'org.springframework.boot:spring-boot-starter' } } project(':api' ) { dependencies { api project(':common' ) api 'javax.validation:validation-api:2.0.1.Final' } } task buildAll { dependsOn subprojects.collect { it.tasks.named('build' ) } description = '构建所有子项目' group = 'build' } task testAll { dependsOn subprojects.collect { it.tasks.named('test' ) } description = '测试所有子项目' group = 'verification' }
8.3 子项目配置示例 📦 common模块 (common/build.gradle)
dependencies { api 'org.apache.commons:commons-lang3:3.12.0' api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' api 'com.google.guava:guava:31.1-jre' implementation 'org.slf4j:slf4j-api:1.7.36' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testImplementation 'org.assertj:assertj-core:3.23.1' } java { withSourcesJar() withJavadocJar() }
🔧 service模块 (service/build.gradle)
plugins { id 'org.springframework.boot' id 'io.spring.dependency-management' } dependencies { implementation project(':api' ) implementation project(':common' ) implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' runtimeOnly 'mysql:mysql-connector-java' testImplementation 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' } jar { enabled = true archiveClassifier = '' } bootJar { enabled = false }
🌐 web模块 (web/build.gradle)
plugins { id 'org.springframework.boot' id 'io.spring.dependency-management' } dependencies { implementation project(':service' ) implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-validation' developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-testcontainers' testImplementation 'org.testcontainers:mysql' } springBoot { buildInfo() mainClass = 'com.example.web.WebApplication' } task buildImage { dependsOn bootBuildImage description = '构建Docker镜像' group = 'build' }
8.4 多项目构建命令 ./gradlew build ./gradlew :web:build ./gradlew :service:test ./gradlew :web:bootRun ./gradlew projects ./gradlew :web:tasks ./gradlew build --parallel ./gradlew :web:build --include-build ./gradlew build --continuous
🔌 9. 自定义插件开发 9.1 插件开发方式 📝 脚本插件(简单场景)
ext { springBootVersion = '2.7.0' junitVersion = '5.9.2' } configurations { integrationTestImplementation.extendsFrom testImplementation integrationTestRuntimeOnly.extendsFrom testRuntimeOnly } sourceSets { integrationTest { java.srcDir 'src/integration-test/java' resources.srcDir 'src/integration-test/resources' } } task integrationTest(type: Test) { testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath useJUnitPlatform() testLogging { events 'passed' , 'skipped' , 'failed' } }
🏗️ buildSrc插件(项目级插件)
plugins { id 'groovy-gradle-plugin' } repositories { gradlePluginPortal() mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-gradle-plugin:2.7.0' } plugins { id 'java' id 'jacoco' } java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 withSourcesJar() withJavadocJar() } repositories { mavenCentral() } dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs += ['-parameters' , '-Xlint:unchecked' ] } test { useJUnitPlatform() finalizedBy jacocoTestReport } jacocoTestReport { dependsOn test reports { xml.required = true html.required = true } }
🎯 独立插件项目
plugins { id 'java-gradle-plugin' id 'groovy' id 'maven-publish' } group = 'com.example' version = '1.0.0' repositories { gradlePluginPortal() mavenCentral() } dependencies { implementation gradleApi() implementation localGroovy() testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0' } gradlePlugin { plugins { myPlugin { id = 'com.example.my-plugin' implementationClass = 'com.example.MyPlugin' displayName = 'My Custom Plugin' description = 'A custom Gradle plugin' } } } publishing { repositories { maven { url = 'https://nexus.company.com/repository/gradle-plugins/' credentials { username = project.findProperty('nexusUsername' ) password = project.findProperty('nexusPassword' ) } } } }
9.2 插件实现示例 🎯 自定义任务类
package com.example.tasksimport org.gradle.api.DefaultTaskimport org.gradle.api.tasks.*class GreetingTask extends DefaultTask { @Input String greeting = 'Hello' @Input String recipient = 'World' @OutputFile File outputFile @TaskAction void greet() { def message = "${greeting}, ${recipient}!" println message if (outputFile) { outputFile.parentFile.mkdirs() outputFile.text = message } } }
🔌 插件主类
package com.exampleimport com.example.tasks.GreetingTaskimport org.gradle.api.Pluginimport org.gradle.api.Projectclass MyPlugin implements Plugin <Project> { @Override void apply(Project project) { def extension = project.extensions.create('myPlugin' , MyPluginExtension) project.tasks.register('greeting' , GreetingTask) { task -> task.greeting = extension.greeting task.recipient = extension.recipient task.outputFile = project.file("${project.buildDir}/greeting.txt" ) } project.tasks.named('build' ) { dependsOn 'greeting' } project.afterEvaluate { println "MyPlugin applied to ${project.name}" } } } class MyPluginExtension { String greeting = 'Hello' String recipient = 'Gradle' }
📝 使用自定义插件
plugins { id 'com.example.my-plugin' version '1.0.0' } myPlugin { greeting = 'Hi' recipient = 'Developer' }
⚡ 10. 性能优化与最佳实践 10.1 构建性能优化 🚀 Gradle Daemon优化详解
org.gradle.daemon =true org.gradle.daemon.idletimeout =3600000 org.gradle.jvmargs =-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
💡 Daemon优化实战案例
案例1:开发环境优化配置
org.gradle.daemon =true org.gradle.jvmargs =-Xmx8g -XX:MaxMetaspaceSize=1g -XX:+UseG1GC org.gradle.daemon.idletimeout =7200000 # 2小时超时 org.gradle.parallel =true org.gradle.configureondemand =true org.gradle.caching =true org.gradle.vfs.watch =true # 文件系统监控(Gradle 6.5+)
案例2:CI/CD环境配置
org.gradle.daemon =false # CI环境不使用daemon org.gradle.jvmargs =-Xmx4g -XX:MaxMetaspaceSize=512m org.gradle.parallel =true # 启用并行构建 org.gradle.caching =true # 启用构建缓存 org.gradle.console =plain # 纯文本输出 org.gradle.logging.level =info # 详细日志 org.gradle.warning.mode =fail # 警告时失败
案例3:容器环境配置
org.gradle.daemon =false # 容器中不使用daemon org.gradle.jvmargs =-Xmx2g -XX:MaxMetaspaceSize=256m -XX:+UseSerialGC org.gradle.parallel =false # 容器中禁用并行(避免资源竞争) org.gradle.workers.max =2 # 限制工作线程数
🔄 并行构建优化
org.gradle.parallel =true org.gradle.workers.max =4 org.gradle.configureondemand =true
💾 构建缓存优化详解
org.gradle.caching =true org.gradle.caching.debug =true org.gradle.unsafe.configuration-cache =true org.gradle.unsafe.configuration-cache-problems =warn // build.gradle - 构建缓存详细配置 buildCache { // ==================== 本地缓存配置 ==================== local { enabled = true // 缓存目录:默认在 ~/.gradle/caches/build-cache-1 directory = file('build-cache') // 清理策略:30天后删除未使用的缓存条目 removeUnusedEntriesAfterDays = 30 // 缓存大小限制(可选) // targetSizeInMB = 5000 // 限制为5GB } // ==================== 远程缓存配置 ==================== remote(HttpBuildCache) { // 远程缓存服务器URL url = 'https://cache.company.com/' // 推送权限:只有CI环境推送缓存 push = project.hasProperty('ci') || System.getenv('CI') != null // 认证信息 credentials { username = project.findProperty('cacheUsername') ?: System.getenv('CACHE_USERNAME') password = project.findProperty('cachePassword') ?: System.getenv('CACHE_PASSWORD') } // 连接配置 allowUntrustedServer = false allowInsecureProtocol = false // 超时配置 // connectionTimeoutMs = 30000 // socketTimeoutMs = 30000 } } // ==================== 任务缓存配置 ==================== // 为自定义任务启用缓存 tasks.register('processFiles', ProcessFilesTask) { // 输入文件 inputFiles.from(fileTree('src/main/resources')) // 输出目录 outputDir = file('build/processed') // 启用缓存 outputs.cacheIf { true } // 缓存键配置 inputs.property('version', project.version) inputs.property('environment', project.findProperty('env') ?: 'dev') } // 禁用特定任务的缓存 tasks.named('someTask') { outputs.doNotCacheIf('Task has side effects') { true } } // ==================== 缓存策略配置 ==================== // 全局缓存策略 tasks.withType(JavaCompile).configureEach { // 启用增量编译 options.incremental = true // 缓存配置 outputs.cacheIf { true } } tasks.withType(Test).configureEach { // 测试任务缓存配置 outputs.cacheIf { // 只有在没有系统属性变化时才缓存 } }
💡 构建缓存实战案例
案例1:企业级缓存配置
buildCache { local { enabled = true directory = file('/opt/gradle-cache' ) removeUnusedEntriesAfterDays = 7 } remote(HttpBuildCache) { url = 'https://gradle-cache.company.com/' push = (System.getenv('CI' ) != null ) && (System.getenv('BRANCH_NAME' ) in ['main' , 'develop' ]) credentials { username = System.getenv('GRADLE_CACHE_USER' ) password = System.getenv('GRADLE_CACHE_PASS' ) } allowUntrustedServer = false connectionTimeoutMs = 10000 socketTimeoutMs = 30000 } }
案例2:开源项目缓存配置
buildCache { local { enabled = true removeUnusedEntriesAfterDays = 14 } remote(HttpBuildCache) { url = 'https://ge.gradle.org/cache/' push = false } } tasks.withType(Javadoc).configureEach { outputs.cacheIf { true } } tasks.withType(Test).configureEach { outputs.cacheIf { !project.hasProperty('forceTests' ) } }
案例3:多环境缓存策略
buildCache { local { enabled = true directory = file("${System.getProperty('user.home')}/.gradle/build-cache" ) removeUnusedEntriesAfterDays = project.hasProperty('dev' ) ? 7 : 30 } remote(HttpBuildCache) { def cacheUrl = project.findProperty('cacheUrl' ) ?: System.getenv('GRADLE_CACHE_URL' ) if (cacheUrl) { url = cacheUrl push = project.hasProperty('pushCache' ) || System.getenv('GRADLE_CACHE_PUSH' ) == 'true' credentials { username = project.findProperty('cacheUser' ) ?: System.getenv('GRADLE_CACHE_USER' ) password = project.findProperty('cachePass' ) ?: System.getenv('GRADLE_CACHE_PASS' ) } } } }
🎯 11. 环境配置管理实战 11.1 多环境配置策略 📝 gradle.properties 环境配置
version =1.0.0-SNAPSHOT group =com.example spring.profiles.active =dev database.url =jdbc:mysql://localhost:3306/myapp_dev database.username =dev_user database.password =dev_password redis.host =localhost redis.port =6379 log.level =DEBUG
🔧 build.gradle 环境配置处理
def environment = project.findProperty('env' ) ?: 'dev' def isProduction = environment == 'prod' def isDevelopment = environment == 'dev' def isTesting = environment == 'test' ext { env = environment dbUrl = project.findProperty('database.url' ) ?: 'jdbc:h2:mem:testdb' dbUsername = project.findProperty('database.username' ) ?: 'sa' dbPassword = project.findProperty('database.password' ) ?: '' redisHost = project.findProperty('redis.host' ) ?: 'localhost' redisPort = project.findProperty('redis.port' ) ?: '6379' logLevel = project.findProperty('log.level' ) ?: 'INFO' springProfiles = project.findProperty('spring.profiles.active' ) ?: 'dev' } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' if (isDevelopment) { developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' } if (isProduction) { runtimeOnly 'mysql:mysql-connector-java' implementation 'io.micrometer:micrometer-registry-prometheus' } if (isTesting) { testImplementation 'org.testcontainers:mysql' testImplementation 'org.testcontainers:redis' } } tasks.named('bootRun' ) { systemProperty 'spring.profiles.active' , springProfiles systemProperty 'database.url' , dbUrl systemProperty 'database.username' , dbUsername systemProperty 'database.password' , dbPassword systemProperty 'redis.host' , redisHost systemProperty 'redis.port' , redisPort if (isDevelopment) { systemProperty 'spring.devtools.restart.enabled' , 'true' systemProperty 'logging.level.com.example' , 'DEBUG' } } tasks.named('test' ) { systemProperty 'spring.profiles.active' , 'test' systemProperty 'database.url' , 'jdbc:h2:mem:testdb' jvmArgs = ['-Xmx1024m' , '-XX:MaxMetaspaceSize=256m' ] } tasks.named('processResources' ) { filesMatching(['**/*.properties' , '**/*.yml' ]) { expand( version: project.version, environment: environment, databaseUrl: dbUrl, databaseUsername: dbUsername, redisHost: redisHost, redisPort: redisPort, logLevel: logLevel ) } }
11.2 配置文件管理策略 📁 配置文件结构
src/main/resources/ ├── application.yml ├── application-dev.yml ├── application-test.yml ├── application-prod.yml ├── config/ │ ├── database-dev.properties │ ├── database-test.properties │ └── database-prod.properties └── templates/ ├── application.yml.template └── logback-spring.xml.template
📝 application.yml 模板
server: port: 8080 servlet: context-path: /api spring: profiles: active: ${environment} application: name: ${project.name} version: ${version} datasource: url: ${databaseUrl} username: ${databaseUsername} password: ${databasePassword} driver-class-name: com.mysql.cj.jdbc.Driver redis: host: ${redisHost} port: ${redisPort} database: 0 logging: level: com.example: ${logLevel} org.springframework: INFO pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{50} - %msg%n" management: endpoints: web: exposure: include: health,info,metrics endpoint: health: show-details: when-authorized
11.3 环境配置实战案例 案例1:多环境构建脚本
def environmentConfigs = [ dev: [ profile: 'dev' , dbUrl: 'jdbc:mysql://localhost:3306/myapp_dev' , dbUser: 'dev_user' , dbPass: 'dev_password' , redisHost: 'localhost' , logLevel: 'DEBUG' , skipTests: false ], test: [ profile: 'test' , dbUrl: 'jdbc:mysql://test-server:3306/myapp_test' , dbUser: 'test_user' , dbPass: System.getenv('TEST_DB_PASSWORD' ), redisHost: 'test-redis.company.com' , logLevel: 'INFO' , skipTests: false ], prod: [ profile: 'prod' , dbUrl: 'jdbc:mysql://prod-cluster:3306/myapp_prod' , dbUser: 'prod_user' , dbPass: System.getenv('PROD_DB_PASSWORD' ), redisHost: 'prod-redis-cluster.company.com' , logLevel: 'WARN' , skipTests: true ] ] def currentEnv = project.findProperty('env' ) ?: 'dev' def config = environmentConfigs[currentEnv]if (!config) { throw new GradleException("Unknown environment: ${currentEnv}" ) } ext { environmentConfig = config } task deployToEnvironment { group = 'deployment' description = "Deploy to ${currentEnv} environment" doLast { println "Deploying to ${currentEnv} environment..." println "Database: ${config.dbUrl}" println "Redis: ${config.redisHost}" println "Log Level: ${config.logLevel}" if (config.skipTests) { println "Skipping tests for ${currentEnv} environment" } else { println "Running tests for ${currentEnv} environment" } } } task validateEnvironment { group = 'verification' description = "Validate ${currentEnv} environment configuration" doLast { println "Validating ${currentEnv} environment..." def requiredEnvVars = [] if (currentEnv == 'test' ) { requiredEnvVars = ['TEST_DB_PASSWORD' ] } else if (currentEnv == 'prod' ) { requiredEnvVars = ['PROD_DB_PASSWORD' , 'PROD_REDIS_PASSWORD' ] } requiredEnvVars.each { envVar -> if (!System.getenv(envVar)) { throw new GradleException("Required environment variable not set: ${envVar}" ) } } println "Environment validation passed for ${currentEnv}" } } tasks.named('build' ) { dependsOn validateEnvironment }
案例2:Docker多环境构建
apply plugin: 'com.palantir.docker' docker { name = "${project.name}:${project.version}-${currentEnv}" dockerfile file('docker/Dockerfile' ) buildArgs([ 'JAR_FILE' : "build/libs/${project.name}-${project.version}.jar" , 'ENVIRONMENT' : currentEnv, 'JAVA_OPTS' : getJavaOpts(currentEnv) ]) files tasks.bootJar.outputs.files files 'docker/entrypoint.sh' files "src/main/resources/application-${currentEnv}.yml" } def getJavaOpts(env) { def javaOpts = [ dev: '-Xmx1g -Xms512m -XX:+UseG1GC' , test: '-Xmx2g -Xms1g -XX:+UseG1GC' , prod: '-Xmx4g -Xms2g -XX:+UseG1GC -XX:+UseStringDeduplication' ] return javaOpts[env] ?: javaOpts['dev' ] } task buildDockerDev { group = 'docker' description = 'Build Docker image for development' dependsOn 'bootJar' finalizedBy 'docker' doFirst { project.ext.currentEnv = 'dev' } } task buildDockerProd { group = 'docker' description = 'Build Docker image for production' dependsOn 'bootJar' finalizedBy 'docker' doFirst { project.ext.currentEnv = 'prod' } }
📊 增量构建优化
task processFiles { inputs.files fileTree('src/main/resources' ) inputs.property 'version' , project.version outputs.dir 'build/processed' outputs.cacheIf { true } doLast { } } class ProcessTask extends DefaultTask { @InputFiles @PathSensitive (PathSensitivity.RELATIVE) FileCollection inputFiles @Input String version @OutputDirectory File outputDir @TaskAction void process() { } }
10.2 依赖解析优化 🔍 依赖解析策略
configurations.all { resolutionStrategy { cacheDynamicVersionsFor 10 , 'minutes' cacheChangingModulesFor 4 , 'hours' componentSelection { all { ComponentSelection selection -> if (selection.candidate.version.contains('alpha' )) { selection.reject('Alpha versions not allowed' ) } } } dependencySubstitution { substitute module('commons-logging:commons-logging' ) with module('org.slf4j:jcl-over-slf4j:1.7.36' ) } } }
📦 仓库优化
repositories { mavenLocal() maven { name = 'Aliyun' url = 'https://maven.aliyun.com/repository/public' } maven { url = 'https://repo.spring.io/milestone' mavenContent { includeGroupByRegex 'org\\.springframework.*' } } mavenCentral() }
10.3 构建脚本优化 🎯 避免配置时间过长
task badTask { def result = expensiveOperation() doLast { println result } } task goodTask { doLast { def result = expensiveOperation() println result } } def expensiveProvider = providers.provider { expensiveOperation() } task betterTask { doLast { println expensiveProvider.get() } }
🔧 任务配置优化
tasks.configureEach { task -> if (task instanceof Test) { task.useJUnitPlatform() task.testLogging { events 'passed' , 'skipped' , 'failed' } } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs.addAll(['-parameters' , '-Xlint:unchecked' ]) }
📌 第五阶段:实战案例与企业级应用 🎯 11. 实战案例:Spring Boot微服务项目 11.1 项目结构设计 microservice-project/ ├── settings.gradle ├── build.gradle ├── gradle.properties ├── buildSrc/ │ ├── build.gradle │ └── src /main /groovy/ ├── common/ │ ├── common-core/ │ ├── common-web/ │ └── common-data/ ├── services/ │ ├── user-service/ │ ├── order -service/ │ └── payment-service/ ├── gateway/ │ └── api-gateway/ ├── infrastructure/ │ ├── config-server/ │ ├── eureka-server/ │ └── monitoring/ └── docker/ ├── docker-compose.yml └── Dockerfile.template
11.2 根项目配置 ⚙️ settings.gradle
rootProject.name = 'microservice-project' include 'common:common-core' include 'common:common-web' include 'common:common-data' include 'services:user-service' include 'services:order-service' include 'services:payment-service' include 'gateway:api-gateway' include 'infrastructure:config-server' include 'infrastructure:eureka-server' include 'infrastructure:monitoring' pluginManagement { plugins { id 'org.springframework.boot' version '2.7.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'com.palantir.docker' version '0.34.0' id 'com.google.cloud.tools.jib' version '3.2.1' } }
📋 根项目 build.gradle
plugins { id 'java' id 'org.springframework.boot' version '2.7.0' apply false id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false } ext { springBootVersion = '2.7.0' springCloudVersion = '2021.0.3' testcontainersVersion = '1.17.3' } allprojects { group = 'com.example.microservice' version = '1.0.0-SNAPSHOT' repositories { maven { url 'https://maven.aliyun.com/repository/public' } mavenCentral() } } subprojects { apply plugin: 'java' apply plugin: 'io.spring.dependency-management' java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } dependencyManagement { imports { mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}" mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "org.testcontainers:testcontainers-bom:${testcontainersVersion}" } } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-actuator' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.testcontainers:junit-jupiter' } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs += ['-parameters' ] } test { useJUnitPlatform() testLogging { events 'passed' , 'skipped' , 'failed' } } } configure(subprojects.findAll { it.path.startsWith(':services:' ) }) { apply plugin: 'org.springframework.boot' dependencies { implementation project(':common:common-core' ) implementation project(':common:common-web' ) implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' } } configure(subprojects.findAll { it.path.startsWith(':common:' ) }) { jar { enabled = true archiveClassifier = '' } bootJar { enabled = false } }
11.3 服务模块配置示例 🔧 user-service/build.gradle
plugins { id 'org.springframework.boot' id 'com.google.cloud.tools.jib' } dependencies { implementation project(':common:common-core' ) implementation project(':common:common-web' ) implementation project(':common:common-data' ) implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' runtimeOnly 'mysql:mysql-connector-java' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.testcontainers:mysql' } springBoot { buildInfo() mainClass = 'com.example.microservice.user.UserServiceApplication' } jib { from { image = 'openjdk:11-jre-slim' } to { image = "microservice/${project.name}:${project.version}" tags = ['latest' ] } container { jvmFlags = ['-Xmx512m' , '-Dfile.encoding=UTF-8' ] ports = ['8080' ] environment = [ 'SPRING_PROFILES_ACTIVE' : 'docker' ] } } configurations { integrationTestImplementation.extendsFrom testImplementation integrationTestRuntimeOnly.extendsFrom testRuntimeOnly } sourceSets { integrationTest { java.srcDir 'src/integration-test/java' resources.srcDir 'src/integration-test/resources' } } task integrationTest(type: Test) { testClassesDirs = sourceSets.integrationTest.output.classesDirs classpath = sourceSets.integrationTest.runtimeClasspath useJUnitPlatform() shouldRunAfter test testLogging { events 'passed' , 'skipped' , 'failed' } } check.dependsOn integrationTest
11.4 构建脚本优化 🎯 buildSrc/src/main/groovy/microservice-conventions.gradle
plugins { id 'java' id 'org.springframework.boot' id 'io.spring.dependency-management' id 'jacoco' } java { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 withSourcesJar() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-sleuth' implementation 'io.micrometer:micrometer-registry-prometheus' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.testcontainers:junit-jupiter' } test { useJUnitPlatform() finalizedBy jacocoTestReport testLogging { events 'passed' , 'skipped' , 'failed' exceptionFormat = 'full' } } jacocoTestReport { dependsOn test reports { xml.required = true html.required = true } afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: [ '**/config/**' , '**/dto/**' , '**/entity/**' , '**/*Application.*' ]) })) } } task healthCheck { group = 'verification' description = '执行服务健康检查' doLast { def port = project.findProperty('server.port' ) ?: '8080' def url = "http://localhost:${port}/actuator/health" try { def response = new URL(url).text println "Health check passed: ${response}" } catch (Exception e) { throw new GradleException("Health check failed: ${e.message}" ) } } }
⚡ 12. 常用命令与工具 12.1 基础构建命令 ./gradlew build ./gradlew clean ./gradlew assemble ./gradlew check ./gradlew test ./gradlew jar ./gradlew :user-service:build ./gradlew :user-service:bootRun ./gradlew build --parallel ./gradlew build --continue ./gradlew dependencies ./gradlew dependencyInsight --dependency spring-core ./gradlew buildEnvironment ./gradlew properties
12.2 性能分析命令 ./gradlew build --profile ./gradlew build --scan ./gradlew build --dry-run ./gradlew build --debug ./gradlew build --info ./gradlew build --stacktrace ./gradlew build --full-stacktrace ./gradlew build --build-cache ./gradlew cleanBuildCache
12.3 任务管理命令 ./gradlew tasks ./gradlew tasks --all ./gradlew :user-service:tasks ./gradlew myTask ./gradlew myTask --rerun-tasks ./gradlew myTask --offline ./gradlew myTask --dry-run ./gradlew help --task myTask
🔧 13. 故障排除与调试 13.1 常见问题解决 ❌ 问题1:构建缓存问题
./gradlew clean build --no-build-cache ./gradlew cleanBuildCache ./gradlew myTask --info
❌ 问题2:依赖解析失败
./gradlew dependencies --refresh-dependencies ./gradlew build --refresh-dependencies ./gradlew buildEnvironment
❌ 问题3:内存不足
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g export GRADLE_OPTS="-Xmx4g" ./gradlew build
❌ 问题4:Daemon问题
./gradlew --stop ./gradlew --no-daemon build ./gradlew --status
13.2 调试技巧 🔍 构建脚本调试
println "Current project: ${project.name}" println "Java version: ${java.sourceCompatibility}" gradle.taskGraph.whenReady { taskGraph -> println "Tasks to execute: ${taskGraph.allTasks*.name}" } gradle.taskGraph.afterTask { task, taskState -> if (taskState.failure) { println "Task ${task.name} failed: ${taskState.failure}" } } gradle.projectsEvaluated { println "All projects evaluated" }
📊 性能分析
class TimingPlugin implements Plugin <Project> { void apply(Project project) { project.gradle.addListener(new TaskExecutionTimeListener()) } } class TaskExecutionTimeListener implements TaskExecutionListener { private long startTime void beforeExecute(Task task) { startTime = System.currentTimeMillis() } void afterExecute(Task task, TaskState state) { long duration = System.currentTimeMillis() - startTime println "${task.path} took ${duration}ms" } }
🏆 14. 最佳实践总结 14.1 项目结构最佳实践 my-gradle-project/ ├── settings.gradle ├── build.gradle ├── gradle.properties ├── buildSrc/ │ ├── build.gradle │ └── src/main/groovy/ ├── gradle/ │ └── wrapper/ ├── common/ ├── services/ ├── infrastructure/ └── docs/
14.2 构建脚本最佳实践 plugins { } group = 'com.example' version = '1.0.0' repositories { } dependencies { } tasks.named('test' ) { } task customTask { }
14.3 性能优化最佳实践 org.gradle.daemon =true org.gradle.parallel =true org.gradle.configureondemand =true org.gradle.caching =true org.gradle.jvmargs =-Xmx4g -XX:MaxMetaspaceSize=1g
14.4 版本管理最佳实践 dependencyResolutionManagement { versionCatalogs { libs { library('spring-boot-starter-web' , 'org.springframework.boot' , 'spring-boot-starter-web' ).version('2.7.0' ) library('junit-jupiter' , 'org.junit.jupiter' , 'junit-jupiter' ).version('5.9.2' ) bundle('spring-boot' , ['spring-boot-starter-web' , 'spring-boot-starter-actuator' ]) } } } dependencies { implementation libs.spring.boot.starter.web testImplementation libs.junit.jupiter implementation libs.bundles.spring.boot }
📚 总结与进阶学习 🎯 学习成果检验 通过本手册的学习,您应该掌握:
✅ 基础知识
Gradle的核心概念和优势
DSL语法和构建脚本编写
任务系统和依赖管理
插件使用和配置
✅ 进阶技能
多项目构建管理
自定义插件开发
性能优化技巧
企业级应用实践
✅ 实战能力
能够设计和实现复杂的构建系统
解决常见的构建问题
优化构建性能
遵循最佳实践
🚀 进阶学习建议
深入学习Gradle内部机制
理解Gradle的构建生命周期
学习任务图和依赖解析机制
企业级实践
学习Gradle Enterprise的使用
掌握大型项目的构建优化
生态系统集成
学习与CI/CD系统的集成
了解与Docker、Kubernetes的结合
插件生态
探索丰富的Gradle插件生态
学习编写高质量的自定义插件
📖 推荐资源
🎉 文章总结
🎯 基础概念 :Gradle核心优势、安装配置、项目结构
📝 DSL语法 :Groovy/Kotlin DSL、构建脚本编写、语法特性
⚙️ 任务系统 :任务定义、依赖关系、输入输出管理
🔍 依赖管理 :配置类型、版本管理、冲突解决
🏗️ 多项目构建 :项目结构设计、配置管理、构建策略
🔌 插件开发 :自定义插件、任务类、扩展开发
⚡ 性能优化 :构建缓存、并行构建、增量构建
🎯 实战案例 :微服务项目、企业级应用、最佳实践
🌟 核心价值
现代化工具 :体验比Maven更快更灵活的构建方式
企业级实践 :适用于大型复杂项目的构建管理
性能导向 :充分利用Gradle的性能优势
生态丰富 :强大的插件生态系统支持