名称: java-maven-helper 描述: Maven 构建系统、依赖管理和 Java 项目配置助手。
Java Maven 依赖与构建助手技能
Maven 构建系统、依赖管理和 Java 项目配置助手。
指令
您是一个 Maven 和 Java 生态系统专家。当被调用时:
-
Maven 项目管理:
- 初始化和配置 Maven 项目
- 管理 pom.xml 配置
- 处理项目结构和组织
- 配置多模块项目
- 使用 Maven 原型
-
依赖管理:
- 添加、更新和移除依赖
- 管理依赖范围
- 处理版本冲突
- 使用依赖管理部分
- 使用物料清单
-
构建配置:
- 配置插件和目标
- 设置构建配置文件
- 管理构建生命周期
- 配置属性和资源
- 处理过滤和资源处理
-
故障排除:
- 修复依赖解析错误
- 调试构建失败
- 解决插件冲突
- 清理损坏的仓库
- 处理版本冲突
-
最佳实践: 提供 Maven 项目组织、依赖管理和构建优化的指导
Maven 基础
项目初始化
# 从原型创建(交互式)
mvn archetype:generate
# 创建快速启动项目(非交互式)
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=my-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.4 \
-DinteractiveMode=false
# 创建 Web 应用程序
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=my-webapp \
-DarchetypeArtifactId=maven-archetype-webapp \
-DinteractiveMode=false
# 创建 Spring Boot 应用程序
mvn archetype:generate \
-DgroupId=com.example \
-DartifactId=my-spring-app \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
基本命令
# 清理构建工件
mvn clean
# 编译项目
mvn compile
# 运行测试
mvn test
# 打包(创建 JAR/WAR)
mvn package
# 安装到本地仓库
mvn install
# 部署到远程仓库
mvn deploy
# 跳过测试
mvn package -DskipTests
# 运行特定测试
mvn test -Dtest=MyTest
# 显示依赖树
mvn dependency:tree
# 显示有效 POM
mvn help:effective-pom
# 运行项目(使用执行插件)
mvn exec:java -Dexec.mainClass="com.example.Main"
使用示例
@java-maven-helper
@java-maven-helper --init-project
@java-maven-helper --add-dependency
@java-maven-helper --fix-dependencies
@java-maven-helper --multi-module
@java-maven-helper --troubleshoot
pom.xml 配置
完整示例
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 项目坐标 -->
<groupId>com.example</groupId>
<artifactId>my-application</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- 项目信息 -->
<name>我的应用程序</name>
<description>一个示例 Maven 项目</description>
<url>https://github.com/user/my-application</url>
<inceptionYear>2024</inceptionYear>
<!-- 组织 -->
<organization>
<name>示例公司</name>
<url>https://example.com</url>
</organization>
<!-- 许可证 -->
<licenses>
<license>
<name>Apache 许可证,版本 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<!-- 开发者 -->
<developers>
<developer>
<id>dev1</id>
<name>开发者姓名</name>
<email>dev@example.com</email>
<organization>示例公司</organization>
<roles>
<role>开发者</role>
</roles>
</developer>
</developers>
<!-- SCM -->
<scm>
<connection>scm:git:git://github.com/user/my-application.git</connection>
<developerConnection>scm:git:ssh://github.com/user/my-application.git</developerConnection>
<url>https://github.com/user/my-application</url>
<tag>HEAD</tag>
</scm>
<!-- 属性 -->
<properties>
<!-- Java 版本 -->
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 依赖版本 -->
<spring.boot.version>3.2.0</spring.boot.version>
<junit.version>5.10.1</junit.version>
<lombok.version>1.18.30</lombok.version>
<slf4j.version>2.0.9</slf4j.version>
<!-- 插件版本 -->
<maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
<maven.surefire.plugin.version>3.2.2</maven.surefire.plugin.version>
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 依赖 -->
<dependencies>
<!-- Spring Boot 启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- 日志记录 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 构建配置 -->
<build>
<!-- 最终工件名称 -->
<finalName>${project.artifactId}</finalName>
<!-- 资源 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<!-- 插件 -->
<plugins>
<!-- 编译器插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<!-- Surefire 插件(测试) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
</plugin>
<!-- Spring Boot 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<!-- 配置文件 -->
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<spring.profiles.active>prod</spring.profiles.active>
</properties>
</profile>
</profiles>
<!-- 仓库 -->
<repositories>
<repository>
<id>central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
</project>
依赖范围
<dependencies>
<!-- 编译(默认):在所有类路径中可用 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.14.0</version>
<scope>compile</scope>
</dependency>
<!-- 提供:在编译时可用,不打包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 运行时:编译不需要,打包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>runtime</scope>
</dependency>
<!-- 测试:仅用于测试 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<!-- 系统:从本地文件系统 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-lib</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/custom-lib.jar</systemPath>
</dependency>
<!-- 导入:用于依赖管理(BOM) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
项目结构
标准 Maven 布局
my-app/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── Main.java
│ │ │ ├── model/
│ │ │ ├── service/
│ │ │ └── repository/
│ │ ├── resources/
│ │ │ ├── application.properties
│ │ │ ├── logback.xml
│ │ │ └── db/
│ │ │ └── migration/
│ │ └── webapp/ (用于 Web 应用)
│ │ ├── WEB-INF/
│ │ │ └── web.xml
│ │ └── index.html
│ └── test/
│ ├── java/
│ │ └── com/
│ │ └── example/
│ │ └── MainTest.java
│ └── resources/
│ └── test.properties
├── target/ (生成的,git忽略)
└── .gitignore
多模块项目
parent-project/
├── pom.xml (父级)
├── module-core/
│ ├── pom.xml
│ └── src/
├── module-api/
│ ├── pom.xml
│ └── src/
├── module-web/
│ ├── pom.xml
│ └── src/
└── module-cli/
├── pom.xml
└── src/
<!-- 父级 pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module-core</module>
<module>module-api</module>
<module>module-web</module>
<module>module-cli</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- 共享依赖版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<!-- 子模块 pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>module-core</artifactId>
<dependencies>
<!-- 无版本的依赖(由父级管理) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
依赖管理
添加依赖
# 手动添加到 pom.xml
# 或在 https://mvnrepository.com 搜索
# 依赖格式:
# <groupId>:<artifactId>:<version>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
依赖分析
# 显示依赖树
mvn dependency:tree
# 显示特定工件的依赖树
mvn dependency:tree -Dincludes=com.google.guava:guava
# 分析依赖
mvn dependency:analyze
# 列出依赖
mvn dependency:list
# 显示可用更新
mvn versions:display-dependency-updates
# 显示插件更新
mvn versions:display-plugin-updates
# 清除本地仓库
mvn dependency:purge-local-repository
版本管理
<!-- 使用属性 -->
<properties>
<spring.version>5.3.31</spring.version>
<junit.version>5.10.1</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<!-- 使用 BOM(物料清单) -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 无版本的依赖(来自 BOM) -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- BOM 中的版本 -->
</dependency>
</dependencies>
排除传递依赖
<dependency>
<groupId>com.example</groupId>
<artifactId>some-library</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
插件配置
常见插件
编译器插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-parameters</arg>
<arg>-Xlint:unchecked</arg>
</compilerArgs>
</configuration>
</plugin>
Surefire 插件(单元测试)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
</includes>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
Failsafe 插件(集成测试)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
JAR 插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Assembly 插件(Fat JAR)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Shade 插件(Uber JAR)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Exec 插件
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<mainClass>com.example.Main</mainClass>
</configuration>
</plugin>
# 使用 exec 插件运行
mvn exec:java
mvn exec:java -Dexec.mainClass="com.example.Main"
mvn exec:java -Dexec.args="arg1 arg2"
构建配置文件
配置文件配置
<profiles>
<!-- 开发配置文件 -->
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<env>development</env>
<database.url>jdbc:h2:mem:testdb</database.url>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
<!-- 生产配置文件 -->
<profile>
<id>prod</id>
<properties>
<env>production</env>
<database.url>jdbc:postgresql://prod-db:5432/app</database.url>
</properties>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<debug>false</debug>
<optimize>true</optimize>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!-- 测试配置文件 -->
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
</profiles>
# 激活配置文件
mvn clean install -Pprod
# 激活多个配置文件
mvn clean install -Pdev,integration-tests
# 列出活动配置文件
mvn help:active-profiles
# 显示配置文件特定设置
mvn help:effective-pom -Pprod
常见问题与解决方案
问题:依赖未找到
# 错误:找不到工件
# 解决方案 1:检查仓库配置
mvn dependency:tree
# 解决方案 2:更新 Maven 元数据
mvn -U clean install # -U 强制更新
# 解决方案 3:清除本地仓库
rm -rf ~/.m2/repository/com/example/problematic-artifact
mvn clean install
# 解决方案 4:检查网络/代理设置
# 添加到 ~/.m2/settings.xml
<settings>
<proxies>
<proxy>
<id>example-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.example.com</host>
<port>8080</port>
</proxy>
</proxies>
</settings>
问题:版本冲突
# 显示依赖冲突
mvn dependency:tree -Dverbose
# 分析依赖冲突
mvn dependency:analyze-duplicate
# 解决方案:使用 dependencyManagement
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
问题:仓库损坏
# 清理本地仓库
mvn dependency:purge-local-repository
# 或手动移除
rm -rf ~/.m2/repository
# 重建
mvn clean install
问题:内存不足
# 增加 Maven 内存
export MAVEN_OPTS="-Xmx2048m -XX:MaxPermSize=512m"
# 或在 .mavenrc 中设置
echo "MAVEN_OPTS='-Xmx2048m'" > ~/.mavenrc
# 对于 Windows(setenv.bat)
set MAVEN_OPTS=-Xmx2048m -XX:MaxPermSize=512m
问题:构建缓慢
# 使用并行构建
mvn -T 4 clean install # 4 个线程
mvn -T 1C clean install # 每个 CPU 核心 1 个线程
# 跳过测试
mvn clean install -DskipTests
# 离线模式(仅使用本地仓库)
mvn -o clean install
# 使用增量构建
mvn clean install -amd # 同时构建依赖项
settings.xml 配置
本地仓库和镜像
<!-- ~/.m2/settings.xml -->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<!-- 本地仓库 -->
<localRepository>${user.home}/.m2/repository</localRepository>
<!-- 镜像 -->
<mirrors>
<mirror>
<id>nexus</id>
<name>Nexus 仓库</name>
<url>https://nexus.example.com/repository/maven-public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<!-- 服务器(认证) -->
<servers>
<server>
<id>nexus-releases</id>
<username>部署</username>
<password>password123</password>
</server>
</servers>
<!-- 配置文件 -->
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>https://nexus.example.com/repository/maven-public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
测试配置
JUnit 5
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.24.2</version>
<scope>test</scope>
</dependency>
</dependencies>
代码覆盖率(JaCoCo)
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
# 生成覆盖率报告
mvn clean test jacoco:report
# 查看报告在 target/site/jacoco/index.html
CI/CD 配置
GitHub Actions
name: Maven 构建
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 设置 JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'maven'
- name: 使用 Maven 构建
run: mvn clean install -B
- name: 运行测试
run: mvn test
- name: 生成覆盖率报告
run: mvn jacoco:report
- name: 上传覆盖率到 Codecov
uses: codecov/codecov-action@v3
with:
files: ./target/site/jacoco/jacoco.xml
GitLab CI
image: maven:3.9-eclipse-temurin-17
variables:
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
cache:
paths:
- .m2/repository
stages:
- build
- test
- package
build:
stage: build
script:
- mvn compile
test:
stage: test
script:
- mvn test
- mvn jacoco:report
artifacts:
reports:
junit:
- target/surefire-reports/TEST-*.xml
paths:
- target/site/jacoco
package:
stage: package
script:
- mvn package -DskipTests
artifacts:
paths:
- target/*.jar
最佳实践总结
项目组织
- 遵循标准 Maven 目录布局
- 对大型项目使用多模块结构
- 保持 pom.xml 清洁和有序
- 使用属性进行版本管理
- 记录自定义配置
依赖管理
- 使用 dependencyManagement 进行版本控制
- 优先使用 BOM 用于框架依赖
- 最小化依赖
- 定期更新依赖
- 使用适当范围
- 排除不必要的传递依赖
构建配置
- 使用构建配置文件用于不同环境
- 正确配置插件
- 使用适当的打包类型
- 显式设置 Java 版本
- 可能时启用并行构建
测试
- 分离单元和集成测试
- 使用 JaCoCo 用于代码覆盖率
- 设置覆盖率阈值
- 在 CI/CD 管道中运行测试
- 使用适当的测试框架
性能
- 使用并行构建(-T)
- 可能时启用离线模式
- 使用 Maven 仓库管理器(Nexus/Artifactory)
- 配置适当的内存设置
- 在 CI/CD 中缓存依赖
快速参考命令
# 项目生命周期
mvn clean # 清理构建工件
mvn compile # 编译源代码
mvn test # 运行测试
mvn package # 创建 JAR/WAR
mvn install # 安装到本地仓库
mvn deploy # 部署到远程仓库
# 依赖管理
mvn dependency:tree # 显示依赖树
mvn dependency:analyze # 分析依赖
mvn versions:display-dependency-updates # 检查更新
# 运行
mvn exec:java # 运行主类
mvn spring-boot:run # 运行 Spring Boot 应用
# 配置文件
mvn clean install -Pprod # 激活配置文件
# 选项
mvn clean install -DskipTests # 跳过测试
mvn clean install -T 4 # 并行构建
mvn clean install -U # 强制更新
mvn clean install -o # 离线模式
# 信息
mvn help:effective-pom # 显示有效 POM
mvn help:active-profiles # 显示活动配置文件
笔记
- 对多模块项目始终使用 dependencyManagement
- 保持 Maven 版本最新
- 使用 Maven Wrapper(mvnw)用于一致构建
- 配置 settings.xml 用于组织范围设置
- 使用配置文件用于环境特定配置
- 启用并行构建用于更快编译
- 设置仓库管理器用于更好性能
- 使用 BOM 管理框架版本
- 记录自定义插件配置
- 定期审计和更新依赖