Skip to content

Maven / Gradle 指南


Maven 生命周期

Maven 的三种标准生命周期,每个生命周期包含多个阶段:

Clean 生命周期(清理)

pre-clean → clean → post-clean

Default 生命周期(构建,核心)

validate → compile → test → package → verify → install → deploy
阶段作用类比
validate验证项目配置检查 pom.xml
compile编译源代码无直接对应
test运行测试phpunit
package打包(JAR/WAR)无直接对应
verify集成测试验证-
install安装到本地仓库类比 composer install 将包加入本地缓存
deploy部署到远程仓库类比 composer publish

Site 生命周期(文档)

pre-site → site → post-site → site-deploy

常用命令

bash
# 编译源码
mvn compile

# 运行测试
mvn test

# 打包(生成 target/xxx.jar)
mvn package

# 清理 + 打包(最常用)
mvn clean package

# 跳过测试打包
mvn clean package -DskipTests

# 安装到本地仓库(供其他模块引用)
mvn clean install

# 启动 Spring Boot 应用
mvn spring-boot:run

pom.xml 结构

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- POM 版本,固定 4.0.0 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- 项目标识(类比 composer.json 的 name) -->
    <groupId>com.example</groupId>         <!-- 类比 vendor,如 laravel/framework 的 laravel -->
    <artifactId>myapp</artifactId>          <!-- 类比 package,如 laravel/framework 的 framework -->
    <version>0.0.1-SNAPSHOT</version>      <!-- 版本号 -->
    <packaging>jar</packaging>              <!-- jar / war / pom -->

    <!-- 父项目(Spring Boot 项目必须) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>

    <!-- 属性定义 -->
    <properties>
        <java.version>21</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- 依赖声明 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- 构建配置 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

scope(依赖作用域)

xml
<dependency>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <scope>compile</scope>   <!-- 默认值,编译/测试/运行都包含 -->
</dependency>
scope编译测试运行说明
compile(默认)常规依赖
provided运行时由容器提供,如 Servlet API
runtime运行时才需要,如 MySQL 驱动
test仅在测试中使用,如 JUnit
system本地 JAR,需指定 path

依赖冲突

当同一个 JAR 被不同版本引入时,Maven 的策略:

  1. 最短路径优先:依赖路径短的优先
  2. 第一声明优先:路径相同,先声明的优先
bash
# 查看依赖树
mvn dependency:tree

# 输出示例
[INFO] com.example:myapp:jar:0.0.1-SNAPSHOT
[INFO] \- org.springframework.boot:spring-boot-starter-web:jar:3.2.0:compile
[INFO]    \- org.springframework:spring-webmvc:jar:6.1.0:compile
[INFO]       \- org.springframework:spring-context:jar:6.1.0:compile
xml
<!-- 排除不必要的传递依赖 -->
<dependency>
    <groupId>some.library</groupId>
    <artifactId>some-lib</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Gradle 快速入门

build.gradle

groovy
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '21'
}

repositories {
    mavenCentral()
    maven { url 'https://maven.aliyun.com/repository/public' }  // 阿里云镜像
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

常用命令

MavenGradle
mvn compilegradle compileJava
mvn testgradle test
mvn packagegradle bootJar
mvn clean packagegradle clean bootJar
mvn spring-boot:rungradle bootRun
mvn dependency:treegradle dependencies

Maven Wrapper(推荐)

bash
# 生成 Maven Wrapper(类似 Composer 的 self-update,但更进一步)
mvn wrapper:wrapper -Dmaven=3.9.6

# 项目目录下会出现:
# mvnw(Linux/Mac 脚本)
# mvnw.cmd(Windows 脚本)
# .mvn/wrapper/

# 之后即便电脑没装 Maven,也能用:
./mvnw clean package     # Mac/Linux
mvnw.cmd clean package   # Windows

Maven Wrapper 让团队统一 Maven 版本,避免"在我电脑上能编译"的问题。相当于 Composer 的 lock 文件锁定版本。


阿里云镜像

xml
<!-- 项目级配置:pom.xml 中的 repositories -->
<repositories>
    <repository>
        <id>aliyun</id>
        <url>https://maven.aliyun.com/repository/public</url>
    </repository>
</repositories>
xml
<!-- 全局配置:~/.m2/settings.xml -->
<settings>
    <mirrors>
        <mirror>
            <id>aliyun</id>
            <mirrorOf>central</mirrorOf>
            <name>阿里云公共仓库</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </mirror>
    </mirrors>
</settings>

和 Composer 配置镜像源的逻辑一样。如果依赖下载慢,先配镜像。


⚠️ 常见坑

1. Maven 编译报错先检查 JDK 版本

xml
<properties>
    <java.version>21</java.version>
</properties>

如果 java.version 配的是 21,但电脑装的 JDK 17,编译报错。这和 composer.jsonrequire 字段指定了 PHP 版本但本地 PHP 版本不够一样。

2. spring-boot-maven-plugin 不能少

没有这个插件,mvn package 生成的 JAR 是普通 JAR,不能 java -jar 运行。

xml
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

3. Maven 和 Gradle 不要混用

选一个即可。Maven 更稳定、生态更成熟;Gradle 更快、配置更简洁。

4. SNAPSHOT 版本的含义

xml
<version>1.0.0-SNAPSHOT</version>  <!-- 开发中的不稳定版本 -->
<version>1.0.0-RELEASE</version>   <!-- 正式发布版本 -->
<version>1.0.0</version>          <!-- 也可以不带后缀 -->

Maven 对 SNAPSHOT 有特殊处理:每次构建都会检查是否有新版本。正式版本只下载一次。

面向 PHP 开发者的 Spring Boot 文档