构建工具是 Java 工程的基石。从 Maven 的约定优于配置到 Gradle 的 DSL 编程式构建,两者各有胜负。理解它们的底层原理——生命周期、依赖传递、插件机制——是构建高效 CI/CD 流水线的必要条件。
1. Maven 核心架构
1.1 生命周期
Maven 有一套固定的三大生命周期,每个生命周期由多个阶段(Phase)组成:
clean 生命周期:
pre-clean → clean → post-clean
default 生命周期(核心构建):
validate → initialize → generate-sources → process-sources
→ generate-resources → process-resources → compile
→ process-classes → generate-test-sources → process-test-sources
→ generate-test-resources → process-test-resources
→ test-compile → process-test-classes → test
→ prepare-package → package → pre-integration-test
→ integration-test → post-integration-test
→ verify → install → deploy
site 生命周期:
pre-site → site → post-site → site-deploy
常用命令与阶段对应:
| 命令 | 执行阶段 | 说明 |
|---|---|---|
mvn compile | compile | 编译主源码 |
mvn test | test | 编译 + 运行测试 |
mvn package | package | 编译 + 测试 + 打包 |
mvn install | install | 打包 + 安装到本地仓库 |
mvn deploy | deploy | 安装 + 发布到远程仓库 |
1.2 POM 继承与 BOM
<!-- 父 POM: 统一管理版本和插件 -->
<project>
<groupId>com.mycompany</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<!-- 依赖版本管理(子模块可引用但不强制继承) -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope> <!-- BOM 导入 -->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 所有子模块强制继承的依赖 -->
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<!-- 子模块 POM -->
<project>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>order-service</artifactId>
<dependencies>
<!-- 版本从 parent 的 dependencyManagement 继承,无需指定 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
1.3 依赖传递与冲突解决
您的项目
├─ A → B(v1.0)
└─ C → B(v2.0)
Maven 冲突解决: 路径最短优先 → 先声明优先
B(v1.0) 路径: 您的项目 → A → B = 2 跳
B(v2.0) 路径: 您的项目 → C → B = 2 跳
路径相同 → 看 POM 中 A 和 C 谁先声明
# 查看依赖树,定位冲突
mvn dependency:tree -Dincludes=org.apache.commons:commons-lang3
# 查看依赖调解结果
mvn dependency:resolve
# 查看依赖分析报告
mvn dependency:analyze
<!-- 排除有漏洞的版本,显式指定安全版本 -->
<dependency>
<groupId>com.some.library</groupId>
<artifactId>problematic-lib</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version> <!-- 安全版本 -->
</dependency>
2. Maven 插件开发
2.1 自定义插件
/**
* @goal greet
* @phase compile
*/
@Mojo(name = "greet", defaultPhase = LifecyclePhase.COMPILE)
public class GreetingMojo extends AbstractMojo {
@Parameter(defaultValue = "World", property = "greet.name")
private String name;
@Parameter(defaultValue = "${project}", readonly = true)
private MavenProject project;
@Override
public void execute() throws MojoExecutionException {
getLog().info("Hello, " + name + "!");
getLog().info("Building: " + project.getArtifactId());
}
}
<!-- 插件 POM -->
<packaging>maven-plugin</packaging>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.9.0</version>
</dependency>
</dependencies>
<!-- 使用自定义插件 -->
<plugin>
<groupId>com.mycompany</groupId>
<artifactId>greeting-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals><goal>greet</goal></goals>
</execution>
</executions>
<configuration>
<name>Developer</name>
</configuration>
</plugin>
3. Gradle 核心概念
3.1 构建生命周期
初始化阶段: 确定参与构建的项目(settings.gradle)
│
配置阶段: 执行所有 build.gradle,创建 Task 图
│
执行阶段: 执行指定的 Task 及其依赖
3.2 Kotlin DSL vs Groovy DSL
// build.gradle.kts(推荐,类型安全)
plugins {
java
id("org.springframework.boot") version "3.2.0"
id("io.spring.dependency-management") version "1.1.4"
}
java {
sourceCompatibility = JavaVersion.VERSION_17
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
}
3.3 Gradle 依赖管理
dependencies {
// 标准 scope 对照
implementation("...") // Maven compile(默认)
compileOnly("...") // Maven provided
runtimeOnly("...") // Maven runtime
testImplementation("...") // Maven test
testCompileOnly("...")
testRuntimeOnly("...")
annotationProcessor("...")
// 平台/ BOM 依赖
implementation(platform("org.springframework.boot:spring-boot-dependencies:3.2.0"))
// 排除传递依赖
implementation("com.some:library:1.0") {
exclude(group = "commons-logging")
}
// 严格版本
implementation("com.google.guava:guava") {
version {
strictly("[32.0, 33.0[")
}
}
}
3.4 自定义 Task
// 自定义 Task 类型
open class GreetingTask : DefaultTask() {
@Input
var greeting: String = "Hello"
@Input
var recipient: String = "World"
@OutputFile
val outputFile: File = project.file("${project.buildDir}/greeting.txt")
@TaskAction
fun greet() {
outputFile.writeText("$greeting, $recipient!")
}
}
// 注册并使用
tasks.register<GreetingTask>("greet") {
greeting = "Hi"
recipient = "Gradle"
}
// 快捷脚本 Task
tasks.register<Copy>("copyConfig") {
from("src/config")
into("${project.buildDir}/config")
include("*.properties")
}
4. 多模块构建
4.1 Maven 多模块
<!-- pom.xml (root) -->
<modules>
<module>common-lib</module>
<module>user-service</module>
<module>order-service</module>
<module>api-gateway</module>
</modules>
# 构建所有模块
mvn clean install
# 只构建特定模块及其依赖
mvn clean install -pl order-service -am
# -pl: projects list
# -am: also-make(构建依赖的模块)
# -amd: also-make-dependents(构建依赖该模块的所有模块)
4.2 Gradle 多模块
// settings.gradle.kts
rootProject.name = "my-platform"
include(
"common-lib",
"user-service",
"order-service",
"api-gateway"
)
// 可选:项目路径自定义
project(":user-service").projectDir = file("services/user")
// 子模块 build.gradle.kts
plugins {
`java-library` // 提供 api() 依赖声明
}
dependencies {
api(project(":common-lib")) // 传递暴露
implementation(project(":internal-lib")) // 不传递
}
Gradle 构建优化:
// gradle.properties
org.gradle.parallel=true // 并行构建模块
org.gradle.caching=true // 构建缓存
org.gradle.configureondemand=true // 按需配置
org.gradle.daemon=true // 守护进程
5. 构建安全与扫描
5.1 依赖漏洞扫描
<!-- Maven: OWASP Dependency-Check -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.4.0</version>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
</configuration>
<executions>
<execution>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
// Gradle: OWASP Dependency-Check
plugins {
id("org.owasp.dependencycheck") version "8.4.0"
}
dependencyCheck {
analyzers {
assemblyEnabled = false
}
failBuildOnCVSS = 7.0f
}
5.2 License 合规检查
<!-- Maven License Plugin -->
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>4.2</version>
<configuration>
<header>LICENSE-HEADER.txt</header>
<includes>
<include>src/main/java/**/*.java</include>
</includes>
</configuration>
</plugin>
6. Maven vs Gradle 选型对比
| 维度 | Maven | Gradle |
|---|---|---|
| 配置语言 | XML | Groovy / Kotlin |
| 学习曲线 | 低(约定优于配置) | 中高(灵活但复杂) |
| 构建速度 | 中 | 高(增量构建 + 构建缓存) |
| 灵活性 | 中 | 高(完整的编程能力) |
| IDE 支持 | 极好 | 极好 |
| 生态成熟度 | 极高 | 高 |
| 多语言构建 | 弱 | 强(原生 C/C++、Android) |
| 脚本调试 | 困难 | 容易 |
选型建议:
- 纯 Java/Kotlin 后端 Spring Boot 项目:两者皆可,团队熟悉哪个用哪个
- Android 项目:Gradle 唯一选择
- 需要复杂构建逻辑(条件编译、动态配置):Gradle 更灵活
- 需要极速构建:Gradle + 构建缓存
延伸阅读
- Spring Boot 核心原理与自动配置 — Starter 与构建工具的关系
- Spring Native 与 GraalVM — AOT 编译的构建配置
- Java 容器化与 K8s 部署 — 构建产物与镜像分层
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。