活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

从零开始轻松创建Maven项目掌握Java开发必备技能解决依赖冲突构建自动化问题让项目开发变得简单高效新手也能快速上手

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-29 09:10:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 引言:Maven是什么?

Maven是Apache软件基金会维护的一个开源项目管理和构建自动化工具,主要服务于基于Java的项目。它采用了一种名为”项目对象模型”(POM)的概念来管理项目的构建、报告和文档。Maven的核心功能包括:

• 项目构建自动化
• 依赖管理系统
• 项目信息管理
• 统一开发结构

对于Java开发者来说,掌握Maven是一项必备技能,它能够极大地简化项目开发过程,提高开发效率。本文将带领大家从零开始学习Maven,即使是新手也能快速上手。

2. Maven的安装与配置

2.1 系统要求

在安装Maven之前,请确保你的系统满足以下要求:

• JDK(Java Development Kit)1.7或更高版本
• 内存:没有最小要求,但建议至少512MB
• 磁盘空间:约10MB

2.2 下载Maven

1. 访问Maven官方网站:https://maven.apache.org/download.cgi
2. 下载最新的二进制zip归档文件(例如:apache-maven-3.8.6-bin.zip)
3. 解压下载的文件到你选择的目录(例如:C:\Program Files\Apache\maven)

2.3 配置环境变量

在Windows系统中配置Maven环境变量:

1. 右键点击”计算机”或”此电脑”,选择”属性”
2. 点击”高级系统设置”
3. 在”系统属性”对话框中,点击”环境变量”
4. 在”系统变量”部分,点击”新建”
5. 变量名输入:MAVEN_HOME
6. 变量值输入Maven的安装路径(例如:C:\Program Files\Apache\maven)
7. 找到”Path”变量,点击”编辑”
8. 在变量值的末尾添加:;%MAVEN_HOME%\bin
9. 点击”确定”保存所有更改

在Linux或macOS系统中配置Maven环境变量:

1. 打开终端
2. 编辑.bashrc或.zshrc文件(取决于你使用的shell):nano ~/.bashrc
3.
  1. 添加以下行:export MAVEN_HOME=/path/to/maven
  2. export PATH=$PATH:$MAVEN_HOME/bin
复制代码
4. 保存文件并退出
5. 运行以下命令使更改生效:source ~/.bashrc
  1. nano ~/.bashrc
复制代码
  1. export MAVEN_HOME=/path/to/maven
  2. export PATH=$PATH:$MAVEN_HOME/bin
复制代码
  1. source ~/.bashrc
复制代码

2.4 验证安装

打开命令提示符或终端,运行以下命令验证Maven是否安装成功:
  1. mvn -version
复制代码

如果安装成功,你将看到类似以下的输出:
  1. Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
  2. Maven home: C:\Program Files\Apache\maven
  3. Java version: 1.8.0_321, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk1.8.0_321\jre
  4. Default locale: en_US, platform encoding: Cp1252
  5. OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
复制代码

3. 创建第一个Maven项目

3.1 使用Maven archetype创建项目

Maven提供了archetype(原型)机制,可以帮助我们快速创建项目骨架。以下是创建一个简单的Java项目的步骤:

1. 打开命令提示符或终端
2. 导航到你想要创建项目的目录
3. 运行以下命令:
  1. mvn archetype:generate -DgroupId=com.example -DartifactId=my-first-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
复制代码

这个命令会创建一个简单的Java项目,其中:

• -DgroupId:指定项目的组ID,通常是公司或组织的倒序域名
• -DartifactId:指定项目的ID,通常是项目的名称
• -DarchetypeArtifactId:指定使用的原型,maven-archetype-quickstart是一个简单的Java项目原型
• -DinteractiveMode=false:指定非交互模式,使用默认值

3.2 项目结构

创建完成后,你会看到一个名为my-first-app的目录,其结构如下:
  1. my-first-app
  2. ├── pom.xml
  3. └── src
  4.     ├── main
  5.     │   └── java
  6.     │       └── com
  7.     │           └── example
  8.     │               └── App.java
  9.     └── test
  10.         └── java
  11.             └── com
  12.                 └── example
  13.                     └── AppTest.java
复制代码

3.3 POM文件解析

打开pom.xml文件,你会看到类似以下内容:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.   <modelVersion>4.0.0</modelVersion>
  4.   <groupId>com.example</groupId>
  5.   <artifactId>my-first-app</artifactId>
  6.   <version>1.0-SNAPSHOT</version>
  7.   <packaging>jar</packaging>
  8.   <name>my-first-app</name>
  9.   <url>http://maven.apache.org</url>
  10.   <properties>
  11.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  12.     <maven.compiler.source>1.8</maven.compiler.source>
  13.     <maven.compiler.target>1.8</maven.compiler.target>
  14.   </properties>
  15.   <dependencies>
  16.     <dependency>
  17.       <groupId>junit</groupId>
  18.       <artifactId>junit</artifactId>
  19.       <version>4.11</version>
  20.       <scope>test</scope>
  21.     </dependency>
  22.   </dependencies>
  23. </project>
复制代码

POM文件是Maven项目的核心,它包含了项目的基本信息、配置、依赖等。主要元素包括:

• modelVersion:指定POM模型的版本
• groupId:项目组的ID,通常是公司或组织的倒序域名
• artifactId:项目的ID,通常是项目的名称
• version:项目的版本
• packaging:项目的打包方式,如jar、war等
• name:项目的显示名称
• url:项目的URL
• properties:项目属性,可以定义一些常量
• dependencies:项目依赖

3.4 构建项目

在项目根目录(包含pom.xml的目录)下,运行以下命令构建项目:
  1. mvn clean package
复制代码

这个命令会执行以下操作:

• clean:清理之前的构建输出
• package:编译代码、运行测试、打包项目

构建成功后,你会在target目录下找到生成的JAR文件:my-first-app-1.0-SNAPSHOT.jar。

3.5 运行项目

你可以使用以下命令运行项目:
  1. java -cp target/my-first-app-1.0-SNAPSHOT.jar com.example.App
复制代码

你会看到输出:
  1. Hello World!
复制代码

4. Maven项目结构解析

Maven采用了一种标准的目录结构,这种结构被称为”约定优于配置”。了解这种结构对于使用Maven非常重要。

4.1 标准目录结构

一个典型的Maven项目结构如下:
  1. project-root/
  2. ├── pom.xml                  # 项目对象模型文件
  3. ├── src/                     # 源代码目录
  4. │   ├── main/                # 主源代码
  5. │   │   ├── java/            # Java源代码
  6. │   │   │   └── com/
  7. │   │   │       └── example/
  8. │   │   │           └── App.java
  9. │   │   ├── resources/       # 资源文件
  10. │   │   │   └── config.properties
  11. │   │   └── webapp/          # Web应用资源(如果是Web项目)
  12. │   │       ├── WEB-INF/
  13. │   │       │   └── web.xml
  14. │   │       └── index.jsp
  15. │   └── test/                # 测试源代码
  16. │       ├── java/            # 测试Java源代码
  17. │       │   └── com/
  18. │       │       └── example/
  19. │       │           └── AppTest.java
  20. │       └── resources/       # 测试资源文件
  21. │           └── test-config.properties
  22. ├── target/                  # 构建输出目录
  23. │   ├── classes/             # 编译后的主类文件
  24. │   ├── test-classes/        # 编译后的测试类文件
  25. │   └── my-first-app-1.0-SNAPSHOT.jar  # 打包后的JAR文件
  26. └── README.md                # 项目说明文件
复制代码

4.2 目录结构说明

• pom.xml:Maven项目的核心配置文件,定义了项目的基本信息、依赖、插件等。
• src/main/java:存放项目的Java源代码。
• src/main/resources:存放项目的资源文件,如配置文件、属性文件等。
• src/main/webapp:Web应用的资源目录,如果是Web项目,则包含WEB-INF目录、JSP文件等。
• src/test/java:存放测试用的Java源代码。
• src/test/resources:存放测试用的资源文件。
• target:Maven构建时生成的输出目录,包含编译后的类文件、打包后的JAR文件等。

4.3 自定义目录结构

虽然Maven推荐使用标准的目录结构,但你也可以根据需要自定义目录结构。在pom.xml中,可以通过以下配置自定义源代码目录:
  1. <build>
  2.     <sourceDirectory>src/custom/java</sourceDirectory>
  3.     <testSourceDirectory>src/test/custom/java</testSourceDirectory>
  4.     <resources>
  5.         <resource>
  6.             <directory>src/custom/resources</directory>
  7.         </resource>
  8.     </resources>
  9.     <testResources>
  10.         <testResource>
  11.             <directory>src/test/custom/resources</directory>
  12.         </testResource>
  13.     </testResources>
  14. </build>
复制代码

5. 依赖管理:添加、更新、删除依赖

Maven最强大的功能之一是依赖管理。它可以自动下载项目所需的库,并管理这些库之间的依赖关系。

5.1 添加依赖

要添加一个依赖,你需要在pom.xml文件的dependencies部分添加一个dependency元素。例如,添加Apache Commons Lang库:
  1. <dependencies>
  2.     <!-- 现有的依赖 -->
  3.     <dependency>
  4.         <groupId>junit</groupId>
  5.         <artifactId>junit</artifactId>
  6.         <version>4.11</version>
  7.         <scope>test</scope>
  8.     </dependency>
  9.    
  10.     <!-- 新添加的依赖 -->
  11.     <dependency>
  12.         <groupId>org.apache.commons</groupId>
  13.         <artifactId>commons-lang3</artifactId>
  14.         <version>3.12.0</version>
  15.     </dependency>
  16. </dependencies>
复制代码

依赖的主要元素包括:

• groupId:依赖的组织或公司ID
• artifactId:依赖的项目ID
• version:依赖的版本
• scope:依赖的范围(可选),如compile、provided、runtime、test等

5.2 依赖范围(Scope)

Maven提供了几种依赖范围,用于控制依赖在不同情况下的可用性:

• compile:默认范围,在所有类路径中都可用,在打包时也会包含进去。
• provided:在编译和测试时可用,但在运行时由JDK或容器提供(如Servlet API)。
• runtime:在运行和测试时可用,但在编译时不需要。
• test:仅在测试时可用,不会打包到最终产品中。
• system:类似于provided,但需要显式提供JAR文件,不推荐使用。

示例:
  1. <dependency>
  2.     <groupId>javax.servlet</groupId>
  3.     <artifactId>javax.servlet-api</artifactId>
  4.     <version>4.0.1</version>
  5.     <scope>provided</scope>
  6. </dependency>
  7. <dependency>
  8.     <groupId>mysql</groupId>
  9.     <artifactId>mysql-connector-java</artifactId>
  10.     <version>8.0.28</version>
  11.     <scope>runtime</scope>
  12. </dependency>
  13. <dependency>
  14.     <groupId>junit</groupId>
  15.     <artifactId>junit</artifactId>
  16.     <version>4.11</version>
  17.     <scope>test</scope>
  18. </dependency>
复制代码

5.3 更新依赖

要更新依赖,只需修改pom.xml中对应依赖的版本号,然后重新构建项目。例如,将JUnit从4.11更新到4.13.2:
  1. <dependency>
  2.     <groupId>junit</groupId>
  3.     <artifactId>junit</artifactId>
  4.     <version>4.13.2</version>
  5.     <scope>test</scope>
  6. </dependency>
复制代码

5.4 删除依赖

要删除依赖,只需从pom.xml文件中移除对应的dependency元素。例如,删除之前添加的Apache Commons Lang库:
  1. <dependencies>
  2.     <dependency>
  3.         <groupId>junit</groupId>
  4.         <artifactId>junit</artifactId>
  5.         <version>4.13.2</version>
  6.         <scope>test</scope>
  7.     </dependency>
  8.    
  9.     <!-- 删除以下依赖 -->
  10.     <!--
  11.     <dependency>
  12.         <groupId>org.apache.commons</groupId>
  13.         <artifactId>commons-lang3</artifactId>
  14.         <version>3.12.0</version>
  15.     </dependency>
  16.     -->
  17. </dependencies>
复制代码

5.5 查找依赖

你可以在Maven中央仓库(https://search.maven.org/)中查找可用的依赖。在搜索框中输入你需要的库的名称,然后从结果中选择合适的版本。

5.6 依赖传递性

Maven的一个强大功能是依赖传递性。如果你添加的依赖依赖于其他库,Maven会自动下载这些传递性依赖。例如,如果你添加Spring Boot Starter Web,它会自动下载Spring框架、Jackson、Tomcat等多个依赖。

5.7 可选依赖

有时候,你可能不希望传递性依赖被自动包含。在这种情况下,可以使用optional元素:
  1. <dependency>
  2.     <groupId>com.example</groupId>
  3.     <artifactId>example-library</artifactId>
  4.     <version>1.0.0</version>
  5.     <optional>true</optional>
  6. </dependency>
复制代码

5.8 排除依赖

如果你不希望包含某个传递性依赖,可以使用exclusions元素:
  1. <dependency>
  2.     <groupId>com.example</groupId>
  3.     <artifactId>example-library</artifactId>
  4.     <version>1.0.0</version>
  5.     <exclusions>
  6.         <exclusion>
  7.             <groupId>org.unwanted</groupId>
  8.             <artifactId>unwanted-library</artifactId>
  9.         </exclusion>
  10.     </exclusions>
  11. </dependency>
复制代码

6. 依赖冲突的识别与解决

在复杂的项目中,依赖冲突是一个常见问题。当项目中的多个依赖依赖于同一个库的不同版本时,就会发生依赖冲突。

6.1 识别依赖冲突

Maven提供了几种方法来识别依赖冲突:

在项目根目录下运行以下命令:
  1. mvn dependency:tree
复制代码

这个命令会显示项目的依赖树,你可以从中看到依赖冲突。例如:
  1. [INFO] com.example:my-first-app:jar:1.0-SNAPSHOT
  2. [INFO] +- junit:junit:jar:4.13.2:test
  3. [INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
  4. [INFO] \- org.apache.commons:commons-lang3:jar:3.12.0:compile
  5. [INFO] \- com.example:library-a:jar:1.0.0:compile
  6. [INFO]    \- org.slf4j:slf4j-api:jar:1.7.25:compile
  7. [INFO] \- com.example:library-b:jar:2.0.0:compile
  8. [INFO]    \- org.slf4j:slf4j-api:jar:1.7.30:compile
复制代码

在上面的例子中,library-a和library-b都依赖于slf4j-api,但版本不同(1.7.25和1.7.30),这就是一个依赖冲突。

运行以下命令:
  1. mvn dependency:analyze
复制代码

这个命令会分析项目中使用的依赖,并报告未使用的依赖和未声明的依赖。

6.2 解决依赖冲突

Maven使用”最近定义优先”(Nearest Definition)策略来解决依赖冲突。这意味着在依赖树中离项目最近的依赖版本会被使用。有几种方法可以显式解决依赖冲突:

在pom.xml中显式声明你想要使用的版本,这个版本会覆盖传递性依赖:
  1. <dependencies>
  2.     <!-- 显式声明slf4j-api的版本 -->
  3.     <dependency>
  4.         <groupId>org.slf4j</groupId>
  5.         <artifactId>slf4j-api</artifactId>
  6.         <version>1.7.30</version>
  7.     </dependency>
  8.    
  9.     <dependency>
  10.         <groupId>com.example</groupId>
  11.         <artifactId>library-a</artifactId>
  12.         <version>1.0.0</version>
  13.     </dependency>
  14.    
  15.     <dependency>
  16.         <groupId>com.example</groupId>
  17.         <artifactId>library-b</artifactId>
  18.         <version>2.0.0</version>
  19.     </dependency>
  20. </dependencies>
复制代码

在pom.xml中使用dependencyManagement元素统一管理依赖版本:
  1. <dependencyManagement>
  2.     <dependencies>
  3.         <dependency>
  4.             <groupId>org.slf4j</groupId>
  5.             <artifactId>slf4j-api</artifactId>
  6.             <version>1.7.30</version>
  7.         </dependency>
  8.     </dependencies>
  9. </dependencyManagement>
  10. <dependencies>
  11.     <dependency>
  12.         <groupId>com.example</groupId>
  13.         <artifactId>library-a</artifactId>
  14.         <version>1.0.0</version>
  15.     </dependency>
  16.    
  17.     <dependency>
  18.         <groupId>com.example</groupId>
  19.         <artifactId>library-b</artifactId>
  20.         <version>2.0.0</version>
  21.     </dependency>
  22. </dependencies>
复制代码

如果某个依赖引入了不想要的版本,可以使用exclusions元素排除它:
  1. <dependencies>
  2.     <dependency>
  3.         <groupId>com.example</groupId>
  4.         <artifactId>library-a</artifactId>
  5.         <version>1.0.0</version>
  6.         <exclusions>
  7.             <exclusion>
  8.                 <groupId>org.slf4j</groupId>
  9.                 <artifactId>slf4j-api</artifactId>
  10.             </exclusion>
  11.         </exclusions>
  12.     </dependency>
  13.    
  14.     <dependency>
  15.         <groupId>com.example</groupId>
  16.         <artifactId>library-b</artifactId>
  17.         <version>2.0.0</version>
  18.     </dependency>
  19.    
  20.     <!-- 显式声明需要的版本 -->
  21.     <dependency>
  22.         <groupId>org.slf4j</groupId>
  23.         <artifactId>slf4j-api</artifactId>
  24.         <version>1.7.30</version>
  25.     </dependency>
  26. </dependencies>
复制代码

6.3 常见依赖冲突及解决方案

许多库使用不同的日志框架,如SLF4J、Log4j、Commons Logging等,这可能导致冲突。解决方案是使用一个桥接库,将所有日志调用重定向到一个统一的日志框架。

例如,使用SLF4J作为统一的日志框架:
  1. <dependencies>
  2.     <!-- SLF4J API -->
  3.     <dependency>
  4.         <groupId>org.slf4j</groupId>
  5.         <artifactId>slf4j-api</artifactId>
  6.         <version>1.7.30</version>
  7.     </dependency>
  8.    
  9.     <!-- Logback实现 -->
  10.     <dependency>
  11.         <groupId>ch.qos.logback</groupId>
  12.         <artifactId>logback-classic</artifactId>
  13.         <version>1.2.3</version>
  14.     </dependency>
  15.    
  16.     <!-- 桥接:将Commons Logging重定向到SLF4J -->
  17.     <dependency>
  18.         <groupId>org.slf4j</groupId>
  19.         <artifactId>jcl-over-slf4j</artifactId>
  20.         <version>1.7.30</version>
  21.     </dependency>
  22.    
  23.     <!-- 桥接:将Log4j重定向到SLF4J -->
  24.     <dependency>
  25.         <groupId>org.slf4j</groupId>
  26.         <artifactId>log4j-over-slf4j</artifactId>
  27.         <version>1.7.30</version>
  28.     </dependency>
  29.    
  30.     <!-- 桥接:将Java Util Logging重定向到SLF4J -->
  31.     <dependency>
  32.         <groupId>org.slf4j</groupId>
  33.         <artifactId>jul-to-slf4j</artifactId>
  34.         <version>1.7.30</version>
  35.     </dependency>
  36. </dependencies>
复制代码

许多库使用不同的XML解析实现,如Xerces、Crimson等,这可能导致冲突。解决方案是显式声明一个XML解析实现:
  1. <dependencies>
  2.     <!-- 显式声明Xerces作为XML解析实现 -->
  3.     <dependency>
  4.         <groupId>xerces</groupId>
  5.         <artifactId>xercesImpl</artifactId>
  6.         <version>2.12.2</version>
  7.     </dependency>
  8. </dependencies>
复制代码

在Web应用中,Servlet API通常由容器提供,但有些依赖可能会引入Servlet API的JAR文件,这可能导致冲突。解决方案是将这些依赖的scope设置为provided:
  1. <dependencies>
  2.     <dependency>
  3.         <groupId>javax.servlet</groupId>
  4.         <artifactId>javax.servlet-api</artifactId>
  5.         <version>4.0.1</version>
  6.         <scope>provided</scope>
  7.     </dependency>
  8. </dependencies>
复制代码

7. 构建自动化:使用Maven进行编译、测试、打包

Maven的另一个强大功能是构建自动化。通过定义一系列的构建阶段(phase)和目标(goal),Maven可以自动完成编译、测试、打包等任务。

7.1 Maven构建生命周期

Maven有三套相互独立的生命周期:

1. Clean Lifecycle:清理项目
2. Default Lifecycle:构建、测试、打包、部署项目
3. Site Lifecycle:生成项目站点

每个生命周期由一系列阶段(phase)组成,这些阶段按顺序执行。例如,Default Lifecycle包括以下主要阶段:

• validate:验证项目是否正确
• compile:编译项目的源代码
• test:使用合适的单元测试框架测试编译后的源代码
• package:将编译后的代码打包成可发布的格式,如JAR
• verify:运行任何检查以验证包是否有效且符合质量标准
• install:将包安装到本地仓库,以供本地其他项目作为依赖使用
• deploy:将最终的包复制到远程仓库,以供其他开发者和项目共享

7.2 常用Maven命令

以下是一些常用的Maven命令:
  1. mvn compile
复制代码

这个命令会执行Default Lifecycle直到compile阶段,包括validate和compile阶段。
  1. mvn test
复制代码

这个命令会执行Default Lifecycle直到test阶段,包括validate、compile和test阶段。
  1. mvn package
复制代码

这个命令会执行Default Lifecycle直到package阶段,包括validate、compile、test和package阶段。
  1. mvn install
复制代码

这个命令会执行Default Lifecycle直到install阶段,包括validate、compile、test、package和install阶段。
  1. mvn deploy
复制代码

这个命令会执行Default Lifecycle的所有阶段,包括validate、compile、test、package、install和deploy阶段。
  1. mvn clean
复制代码

这个命令会执行Clean Lifecycle的所有阶段,删除target目录及其内容。

你可以组合多个生命周期阶段,例如:
  1. mvn clean package
复制代码

这个命令会先执行Clean Lifecycle,然后执行Default Lifecycle直到package阶段。

7.3 跳过测试

有时候,你可能想要跳过测试阶段,可以使用以下命令:
  1. mvn package -DskipTests
复制代码

或者:
  1. mvn package -Dmaven.test.skip=true
复制代码

7.4 指定目标

除了生命周期阶段,你还可以直接指定插件目标:
  1. mvn compiler:compile
复制代码

这个命令会直接执行compiler插件的compile目标。

7.5 自定义构建

你可以在pom.xml中配置插件来自定义构建过程。例如,配置Java编译器版本:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-compiler-plugin</artifactId>
  6.             <version>3.8.1</version>
  7.             <configuration>
  8.                 <source>1.8</source>
  9.                 <target>1.8</target>
  10.             </configuration>
  11.         </plugin>
  12.     </plugins>
  13. </build>
复制代码

7.6 多模块项目

对于大型项目,你可能需要使用多模块项目结构。在多模块项目中,有一个父POM和多个子模块。父POM通常包含:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.     <modelVersion>4.0.0</modelVersion>
  4.     <groupId>com.example</groupId>
  5.     <artifactId>my-multi-module-project</artifactId>
  6.     <version>1.0-SNAPSHOT</version>
  7.     <packaging>pom</packaging>
  8.     <modules>
  9.         <module>module-a</module>
  10.         <module>module-b</module>
  11.         <module>webapp</module>
  12.     </modules>
  13.     <properties>
  14.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15.         <maven.compiler.source>1.8</maven.compiler.source>
  16.         <maven.compiler.target>1.8</maven.compiler.target>
  17.     </properties>
  18.     <dependencyManagement>
  19.         <dependencies>
  20.             <!-- 统一管理依赖版本 -->
  21.             <dependency>
  22.                 <groupId>junit</groupId>
  23.                 <artifactId>junit</artifactId>
  24.                 <version>4.13.2</version>
  25.                 <scope>test</scope>
  26.             </dependency>
  27.         </dependencies>
  28.     </dependencyManagement>
  29.     <build>
  30.         <pluginManagement>
  31.             <plugins>
  32.                 <!-- 统一管理插件版本 -->
  33.                 <plugin>
  34.                     <groupId>org.apache.maven.plugins</groupId>
  35.                     <artifactId>maven-compiler-plugin</artifactId>
  36.                     <version>3.8.1</version>
  37.                 </plugin>
  38.             </plugins>
  39.         </pluginManagement>
  40.     </build>
  41. </project>
复制代码

子模块的POM文件会继承父POM的配置:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.     <modelVersion>4.0.0</modelVersion>
  4.     <parent>
  5.         <groupId>com.example</groupId>
  6.         <artifactId>my-multi-module-project</artifactId>
  7.         <version>1.0-SNAPSHOT</version>
  8.     </parent>
  9.     <artifactId>module-a</artifactId>
  10.     <packaging>jar</packaging>
  11.     <dependencies>
  12.         <dependency>
  13.             <groupId>junit</groupId>
  14.             <artifactId>junit</artifactId>
  15.             <scope>test</scope>
  16.         </dependency>
  17.     </dependencies>
  18. </project>
复制代码

在多模块项目中,你可以在父项目目录下运行Maven命令,Maven会按照模块之间的依赖关系顺序构建所有模块:
  1. mvn clean package
复制代码

8. 常用Maven插件介绍

Maven插件是Maven的核心功能之一,它们提供了各种功能,如编译代码、运行测试、打包应用、生成文档等。以下是一些常用的Maven插件:

8.1 Maven Compiler Plugin

Maven Compiler Plugin用于编译Java源代码。它是Maven的默认插件,通常不需要显式配置,但你可以自定义它的配置:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-compiler-plugin</artifactId>
  6.             <version>3.8.1</version>
  7.             <configuration>
  8.                 <source>1.8</source>
  9.                 <target>1.8</target>
  10.                 <encoding>UTF-8</encoding>
  11.                 <compilerArgs>
  12.                     <arg>-Xlint:all</arg>
  13.                 </compilerArgs>
  14.                 <showWarnings>true</showWarnings>
  15.                 <showDeprecation>true</showDeprecation>
  16.             </configuration>
  17.         </plugin>
  18.     </plugins>
  19. </build>
复制代码

8.2 Maven Surefire Plugin

Maven Surefire Plugin用于运行单元测试。它也是Maven的默认插件,但你可以自定义它的配置:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-surefire-plugin</artifactId>
  6.             <version>3.0.0-M5</version>
  7.             <configuration>
  8.                 <includes>
  9.                     <include>**/*Test.java</include>
  10.                     <include>**/*Tests.java</include>
  11.                 </includes>
  12.                 <excludes>
  13.                     <exclude>**/*IT.java</exclude>
  14.                     <exclude>**/*IntegrationTest.java</exclude>
  15.                 </excludes>
  16.                 <skipTests>false</skipTests>
  17.                 <testFailureIgnore>true</testFailureIgnore>
  18.                 <parallel>methods</parallel>
  19.                 <threadCount>4</threadCount>
  20.             </configuration>
  21.         </plugin>
  22.     </plugins>
  23. </build>
复制代码

8.3 Maven Failsafe Plugin

Maven Failsafe Plugin用于运行集成测试。它与Surefire Plugin类似,但专门用于运行集成测试:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-failsafe-plugin</artifactId>
  6.             <version>3.0.0-M5</version>
  7.             <configuration>
  8.                 <includes>
  9.                     <include>**/*IT.java</include>
  10.                     <include>**/*IntegrationTest.java</include>
  11.                 </includes>
  12.                 <excludes>
  13.                     <exclude>**/*Test.java</exclude>
  14.                     <exclude>**/*Tests.java</exclude>
  15.                 </excludes>
  16.             </configuration>
  17.             <executions>
  18.                 <execution>
  19.                     <goals>
  20.                         <goal>integration-test</goal>
  21.                         <goal>verify</goal>
  22.                     </goals>
  23.                 </execution>
  24.             </executions>
  25.         </plugin>
  26.     </plugins>
  27. </build>
复制代码

8.4 Maven Jar Plugin

Maven Jar Plugin用于构建JAR文件:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-jar-plugin</artifactId>
  6.             <version>3.2.0</version>
  7.             <configuration>
  8.                 <archive>
  9.                     <manifest>
  10.                         <addClasspath>true</addClasspath>
  11.                         <mainClass>com.example.App</mainClass>
  12.                     </manifest>
  13.                 </archive>
  14.             </configuration>
  15.         </plugin>
  16.     </plugins>
  17. </build>
复制代码

8.5 Maven War Plugin

Maven War Plugin用于构建WAR文件(Web应用归档):
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-war-plugin</artifactId>
  6.             <version>3.3.1</version>
  7.             <configuration>
  8.                 <warSourceDirectory>src/main/webapp</warSourceDirectory>
  9.                 <failOnMissingWebXml>false</failOnMissingWebXml>
  10.             </configuration>
  11.         </plugin>
  12.     </plugins>
  13. </build>
复制代码

8.6 Maven Shade Plugin

Maven Shade Plugin用于构建可执行的Uber JAR(包含所有依赖的JAR):
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-shade-plugin</artifactId>
  6.             <version>3.2.4</version>
  7.             <executions>
  8.                 <execution>
  9.                     <phase>package</phase>
  10.                     <goals>
  11.                         <goal>shade</goal>
  12.                     </goals>
  13.                     <configuration>
  14.                         <transformers>
  15.                             <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
  16.                                 <mainClass>com.example.App</mainClass>
  17.                             </transformer>
  18.                         </transformers>
  19.                     </configuration>
  20.                 </execution>
  21.             </executions>
  22.         </plugin>
  23.     </plugins>
  24. </build>
复制代码

8.7 Maven Assembly Plugin

Maven Assembly Plugin用于创建自定义的程序集,如分发包:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-assembly-plugin</artifactId>
  6.             <version>3.3.0</version>
  7.             <configuration>
  8.                 <descriptorRefs>
  9.                     <descriptorRef>jar-with-dependencies</descriptorRef>
  10.                 </descriptorRefs>
  11.                 <archive>
  12.                     <manifest>
  13.                         <mainClass>com.example.App</mainClass>
  14.                     </manifest>
  15.                 </archive>
  16.             </configuration>
  17.             <executions>
  18.                 <execution>
  19.                     <id>make-assembly</id>
  20.                     <phase>package</phase>
  21.                     <goals>
  22.                         <goal>single</goal>
  23.                     </goals>
  24.                 </execution>
  25.             </executions>
  26.         </plugin>
  27.     </plugins>
  28. </build>
复制代码

8.8 Maven Site Plugin

Maven Site Plugin用于生成项目站点和文档:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-site-plugin</artifactId>
  6.             <version>3.9.1</version>
  7.         </plugin>
  8.     </plugins>
  9. </build>
复制代码

8.9 Maven Release Plugin

Maven Release Plugin用于自动化发布过程:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.apache.maven.plugins</groupId>
  5.             <artifactId>maven-release-plugin</artifactId>
  6.             <version>3.0.0-M4</version>
  7.             <configuration>
  8.                 <tagNameFormat>v@{project.version}</tagNameFormat>
  9.                 <autoVersionSubmodules>true</autoVersionSubmodules>
  10.             </configuration>
  11.         </plugin>
  12.     </plugins>
  13. </build>
复制代码

8.10 Maven Exec Plugin

Maven Exec Plugin用于执行Java程序:
  1. <build>
  2.     <plugins>
  3.         <plugin>
  4.             <groupId>org.codehaus.mojo</groupId>
  5.             <artifactId>exec-maven-plugin</artifactId>
  6.             <version>3.0.0</version>
  7.             <configuration>
  8.                 <mainClass>com.example.App</mainClass>
  9.             </configuration>
  10.         </plugin>
  11.     </plugins>
  12. </build>
复制代码

你可以使用以下命令运行程序:
  1. mvn exec:java
复制代码

9. Maven最佳实践

为了更有效地使用Maven,以下是一些最佳实践:

9.1 使用一致的版本号

在多模块项目中,使用父POM的properties部分定义依赖和插件的版本号,以保持一致性:
  1. <properties>
  2.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  3.     <maven.compiler.source>1.8</maven.compiler.source>
  4.     <maven.compiler.target>1.8</maven.compiler.target>
  5.    
  6.     <!-- 依赖版本 -->
  7.     <junit.version>4.13.2</junit.version>
  8.     <slf4j.version>1.7.30</slf4j.version>
  9.    
  10.     <!-- 插件版本 -->
  11.     <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
  12.     <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
  13. </properties>
  14. <dependencyManagement>
  15.     <dependencies>
  16.         <dependency>
  17.             <groupId>junit</groupId>
  18.             <artifactId>junit</artifactId>
  19.             <version>${junit.version}</version>
  20.             <scope>test</scope>
  21.         </dependency>
  22.         <dependency>
  23.             <groupId>org.slf4j</groupId>
  24.             <artifactId>slf4j-api</artifactId>
  25.             <version>${slf4j.version}</version>
  26.         </dependency>
  27.     </dependencies>
  28. </dependencyManagement>
  29. <build>
  30.     <pluginManagement>
  31.         <plugins>
  32.             <plugin>
  33.                 <groupId>org.apache.maven.plugins</groupId>
  34.                 <artifactId>maven-compiler-plugin</artifactId>
  35.                 <version>${maven-compiler-plugin.version}</version>
  36.             </plugin>
  37.             <plugin>
  38.                 <groupId>org.apache.maven.plugins</groupId>
  39.                 <artifactId>maven-surefire-plugin</artifactId>
  40.                 <version>${maven-surefire-plugin.version}</version>
  41.             </plugin>
  42.         </plugins>
  43.     </pluginManagement>
  44. </build>
复制代码

9.2 使用依赖管理

在多模块项目中,使用父POM的dependencyManagement部分统一管理依赖版本:
  1. <dependencyManagement>
  2.     <dependencies>
  3.         <dependency>
  4.             <groupId>org.springframework.boot</groupId>
  5.             <artifactId>spring-boot-dependencies</artifactId>
  6.             <version>2.5.5</version>
  7.             <type>pom</type>
  8.             <scope>import</scope>
  9.         </dependency>
  10.         <dependency>
  11.             <groupId>junit</groupId>
  12.             <artifactId>junit</artifactId>
  13.             <version>4.13.2</version>
  14.             <scope>test</scope>
  15.         </dependency>
  16.     </dependencies>
  17. </dependencyManagement>
复制代码

9.3 使用插件管理

使用父POM的pluginManagement部分统一管理插件版本:
  1. <build>
  2.     <pluginManagement>
  3.         <plugins>
  4.             <plugin>
  5.                 <groupId>org.apache.maven.plugins</groupId>
  6.                 <artifactId>maven-compiler-plugin</artifactId>
  7.                 <version>3.8.1</version>
  8.                 <configuration>
  9.                     <source>1.8</source>
  10.                     <target>1.8</target>
  11.                 </configuration>
  12.             </plugin>
  13.             <plugin>
  14.                 <groupId>org.apache.maven.plugins</groupId>
  15.                 <artifactId>maven-surefire-plugin</artifactId>
  16.                 <version>3.0.0-M5</version>
  17.             </plugin>
  18.         </plugins>
  19.     </pluginManagement>
  20. </build>
复制代码

9.4 使用资源过滤

使用资源过滤功能,可以在构建时动态替换资源文件中的占位符:
  1. <build>
  2.     <resources>
  3.         <resource>
  4.             <directory>src/main/resources</directory>
  5.             <filtering>true</filtering>
  6.         </resource>
  7.     </resources>
  8. </build>
复制代码

在资源文件中,你可以使用${...}占位符:
  1. # application.properties
  2. application.name=${project.name}
  3. application.version=${project.version}
复制代码

9.5 使用多环境配置

使用Maven Profile支持多环境配置:
  1. <profiles>
  2.     <profile>
  3.         <id>dev</id>
  4.         <activation>
  5.             <activeByDefault>true</activeByDefault>
  6.         </activation>
  7.         <properties>
  8.             <environment>dev</environment>
  9.         </properties>
  10.     </profile>
  11.     <profile>
  12.         <id>test</id>
  13.         <properties>
  14.             <environment>test</environment>
  15.         </properties>
  16.     </profile>
  17.     <profile>
  18.         <id>prod</id>
  19.         <properties>
  20.             <environment>prod</environment>
  21.         </properties>
  22.     </profile>
  23. </profiles>
复制代码

你可以使用以下命令激活特定的Profile:
  1. mvn package -Pprod
复制代码

9.6 使用Maven Wrapper

Maven Wrapper是一个脚本和属性文件的集合,允许你在没有安装Maven的情况下构建项目。要添加Maven Wrapper到你的项目,运行以下命令:
  1. mvn -N io.takari:maven:wrapper
复制代码

这会在你的项目根目录下创建mvnw、mvnw.cmd和.mvn目录。之后,你可以使用这些脚本而不是系统安装的Maven:
  1. # Unix/Linux/macOS
  2. ./mvnw clean package
  3. # Windows
  4. mvnw.cmd clean package
复制代码

9.7 定期清理本地仓库

定期清理你的本地Maven仓库,以避免过时或损坏的依赖:
  1. # Unix/Linux/macOS
  2. find ~/.m2/repository -name "*.lastUpdated" -delete
  3. # Windows
  4. del /s /q %USERPROFILE%\.m2\repository\*.lastUpdated
复制代码

9.8 使用Maven仓库管理器

使用Maven仓库管理器(如Nexus、Artifactory)来管理依赖,可以提高构建速度,减少对外部仓库的依赖,并允许你托管内部库。

9.9 编写测试

编写单元测试和集成测试,并使用Maven的Surefire和Failsafe插件运行它们。这有助于确保代码质量,并在早期发现问题。

9.10 使用持续集成

将Maven项目与持续集成服务器(如Jenkins、Travis CI、GitHub Actions)集成,以自动构建、测试和部署你的项目。

10. 总结

Maven是一个强大的项目管理和构建自动化工具,它通过标准化的项目结构、依赖管理和构建生命周期,极大地简化了Java项目的开发过程。本文从零开始介绍了Maven的安装、配置、项目创建、依赖管理、依赖冲突解决、构建自动化等内容,并提供了一些常用的Maven插件和最佳实践。

通过掌握Maven,你可以:

• 快速创建标准化的Java项目
• 管理项目依赖,避免依赖冲突
• 自动化构建过程,提高开发效率
• 使用各种插件扩展功能
• 遵循最佳实践,确保项目质量

无论是新手还是有经验的开发者,都可以从Maven中受益,使项目开发变得简单高效。希望本文能够帮助你快速上手Maven,并在实际项目中应用这些知识。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则