baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • 其他

  • Spring

  • springboot

  • RPC

  • netty

  • mybatis

  • maven

    • linux安装maven
    • maven
    • maven摘录
      • 一、什么是Maven?
      • 1.系统要求
      • 2.安装步骤
        • 2.1.JDK安装
        • JDK下载
        • JDK安装
        • 校验安装
        • 2.2.Maven安装
        • Maven下载
        • Maven安装
        • 校验安装
      • 1.POM文件
      • 2.使用Maven构建项目
        • 2.1.使用命令行
        • 2.2.使用IDEA
      • 3.使用Maven打包项目
        • 3.1.使用命令行打包
        • 3.2.使用IDEA
      • 一、创建一个maven项目
      • 1.使用Idea创建一个maven项目
      • 2.项目目录结构
      • 3.pom文件
      • 1.项目目录结构遵循约定
      • 1.说明
      • 2.简单配置
      • 3.其他配置
      • 1.说明
      • 2.坐标元素
      • 3.项目构件的文件名
      • 1.使用maven怎么引入依赖?
      • 2.maven依赖范围
      • 3.依赖范围与classpath的关系
      • 4.scope与运行classpath
      • 1.说明
      • 2.依赖范围对传递性依赖的影响
      • 1.第一原则:路径近者优先。
      • 2.第二原则:第一声明者优先。
      • 1.排除依赖
      • 2.归类依赖
      • 3.优化依赖
      • 一、引入
      • 1.本地仓库
      • 2.远程仓库
      • 3.中央仓库
      • 4.私服
      • 5.其他远程仓库
      • 1.在项目POM中配置远程仓库(项目)
      • 2.在用户配置中配置镜像仓库(全局)
      • 一、私服
      • 1.安装和配置
      • 2.上传(deploy)配置
      • 一、maven的生命周期
      • 1.生命周期介绍
      • 2.生命周期详解
        • 2.1.三套生命周期
        • 2.2.生命周期内部的阶段
        • 2.3.clean生命周期
        • 2.4.default生命周期
        • 2.5.site生命周期
        • 2.6.mvn命令和生命周期
      • 1.插件目标
      • 2.插件绑定
      • 3.内置绑定
        • 3.1.说明
        • 3.2.clean生命周期阶段与插件目标的绑定关系
        • 3.3.default生命周期阶段与插件目标的绑定关系(打包类型:jar)
        • 3.4.site生命周期阶段与插件目标的绑定关系
        • 3.5.构建过程验证
      • 4.插件配置
        • 4.1.命令行插件配置
        • 4.2.pom文件中插件全局配置
      • 5.获取插件信息
        • 5.1.在线插件信息
        • 5.2.使用 maven-help-plugin 描述插件
        • 5.3.从命令行调用插件
      • 6.插件解析
        • 6.1.插件仓库
        • 6.2.插件的默认groupId
        • 6.3.解析插件版本
        • 6.4.解析插件前缀
      • 一、灵活构建
      • 1.三大特性
      • 2.属性
        • 2.1.自定义属性
        • 2.2.内置属性
        • 2.3.POM属性
        • 2.4.settings属性
        • 2.5.Java系统属性
        • 2.6.环境变量属性
      • 3.资源过滤
        • 3.1.遇到的问题
        • 3.2.解决
        • 3.3.示例
      • 4.Maven Profile
        • 4.1.针对不同环境的profile
        • 4.2.激活profile
        • 4.3.查看当前激活的profile
        • 4.4.列出所有的profile
      • 1.为什么使用聚合?
      • 2.聚合配置
        • 2.1.聚合模块pom配置
        • 2.2.聚合模块相对位置
        • 2.3.聚合模块意义
        • 2.4.聚合模块构建
      • 1.为什么使用继承?
      • 2.继承配置
        • 2.1.项目继承的配置
        • 2.2.可继承的pom元素
        • 2.3.依赖管理
        • 2.4.插件管理
      • 1.目的
      • 2.与其他模块关系
      • 3.共同点
      • 4.实际使用
      • 1.介绍
        • 1.1.反应堆
        • 1.2.单模块项目的反应堆
        • 1.3.多模块项目的反应堆
      • 2.反应堆构建顺序
      • 3.裁剪反应堆
        • 3.1.说明
        • 3.2.裁剪反应堆选项
  • 单元测试

  • 常见框架
  • maven
xugaoyi
2024-02-22
目录

maven摘录

# 1 快速入门

# 一、什么是Maven?

Maven 是一个项目管理和整合工具。Maven 为开发者提供了一套完整的构建生命周期框架。开发团队几乎不用花多少时间就能够自动完成工程的基础构建配置,因为 Maven 使用了一个标准的目录结构和一个默认的构建生命周期。

在有多个开发团队环境的情况下,Maven 能够在很短的时间内使得每项工作都按照标准进行。因为大部分的工程配置操作都非常简单并且可复用,在创建报告、检查、构建和测试自动配置时,Maven 可以让开发者的工作变得更简单。

Maven 能够帮助开发者完成以下工作:

  • 构建
  • 文档生成
  • 报告
  • 依赖
  • SCMs
  • 发布
  • 分发
  • 邮件列表

总的来说,Maven 简化了工程的构建过程,并对其标准化。它无缝衔接了编译、发布、文档生成、团队合作和其他任务。Maven 提高了重用性,负责了大部分构建相关的任务。

# 二、如何安装Maven?

# 1.系统要求

项目 要求
JDK Maven 3.3 要求 JDK 1.7 或以上 Maven 3.2 要求 JDK 1.6 或以上 Maven 3.0/3.1 要求 JDK 1.5 或以上
内存 没有最低要求
磁盘 Maven 自身安装需要大约 10 MB 空间。除此之外,额外的磁盘空间将用于你的本地 Maven 仓库。你本地仓库的大小取决于使用情况,但预期至少 500 MB
操作系统 没有最低要求

# 2.安装步骤

# 2.1.JDK安装

# JDK下载

推荐在oracle官网下载JDK:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html

image-20240105125609929

# JDK安装

在MacOS环境下可以直接通过dmg程序进行安装,安装程序会自动配置环境,无需手动配置。

# 校验安装

可以在terminal中使用以下命令检查JDK是否安装成功。

java -version
1

如出现以下输出,代表JDK安装正常。

java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)
1
2
3

# 2.2.Maven安装

# Maven下载

从以下网址下载 Maven 3.8.1:http://maven.Apache.org/download.html (opens new window)

image-20240105125624885

# Maven安装

1.解压文件到你想要的位置来安装 Maven 3.8.1,你会得到 apache-maven-3.8.1 子目录。

2.添加 M2_HOME、M2、MAVEN_OPTS 到环境变量中。

Mac环境下可以使用以下任意一种方法添加环境变量

名称 步骤1 步骤2 步骤3
修改全局环境变量 在terminal输入:(可能需要使用sudo命令)sudo vi /etc/bashrc 在文件的末尾追加:export M2_HOME=改成你解压到的地址/apache-maven-3.8.4 export M2=$M2_HOME/bin export MAVEN_OPTS=-Xms256m -Xmx512m export PATH=$M2:$PATH 让修改的文件生效source /etc/bashrc
修改当前用户环境变量 在terminal输入:vi ~/.bash_rc 让修改的文件生效source ~/.bash_rc

# 校验安装

在terminal中输入

mvn --version
1

展示内容为如下所示,说明安装成功

Apache Maven 3.8.4
Maven home: 你解压到的地址/apache-maven-3.8.4
Java version: 1.8.0_291, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"
1
2
3
4
5

# 三、如何使用Maven构建项目?

# 1.POM文件

POM 代表工程对象模型。它是使用 Maven 工作时的基本组建,是一个 xml 文件。它被放在工程根目录下,文件命名为 pom.xml。

POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程。POM 也包含了目标和插件。当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标。

常见的POM文件格式如下:

<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.sankuai</groupId>
   <artifactId>mavenTest</artifactId>
   <version>1.0</version>

</project>
1
2
3
4
5
6
7
8
9
10
11

需要说明的是每个工程应该只有一个 POM 文件。

  • 所有的 POM 文件需要 project 元素和三个必须的字段:groupId, artifactId,version。
  • 在仓库中的工程标识为 groupId:artifactId:version
  • POM.xml 的根元素是 project,它有三个主要的子节点:
节点 描述
groupId 这是工程组的标识。它在一个组织或者项目中通常是唯一的。通常我们使用公司的域名倒置作为groupId,例如,三快在线的groupId为com.sankuai。
artifactId 这是工程的标识。它通常是工程的名称。例如,一个用来测试maven的项目名称为mavenTest。groupId 和 artifactId 一起定义了 artifact 在仓库中的位置。
version 这是工程的版本号。在 artifact 的仓库中,它用来区分不同的版本。例如: com.sankuai:mavenTest:1.0.0 com.sankuai:mavenTest:1.0.1

一般来说我们不需要自己手动编写POM文件,当使用Maven构建项目时会自动生成对应的POM文件。

# 2.使用Maven构建项目

Maven 使用**原型(archetype)**插件创建工程,并且Maven内置了大量的JAVA原型模版。通常我们有两种方法使用Maven来创建项目。在下面的例子中将演示两种使用Maven构建Java项目的方法。

# 2.1.使用命令行

1.打开命令行工具,跳转到合适的项目目录下,在此处使用~/workspace作为演示目录

cd ~/workspace
1

2.使用Maven命令行构建项目

mvn archetype:generate -DgroupId=com.sankuai -DartifactId=mavenTest -DarchetypeArtifactId=maven-archetype-quickstart
1

参数说明:

archetype:generate 构建项目

-DgroupId=com.sankuai 工程组设置为公司的名称

-DartifactId=mavenTest 指明项目名称

-DarchetypeArtifactId=maven-archetype-quickstart 使用Java原型插件,这个插件也是项目工程中使用最频繁的插件。

执行命令之后会展示如下输出信息,说明项目构建成功。

[INFO] Scanning for projects...
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/plugins/maven-metadata.xml
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/com/dianping/maven/plugins/maven-metadata.xml
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/unidal/maven/plugins/maven-metadata.xml
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/jvnet/hudson/tools/maven-metadata.xml
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/unidal/maven/plugins/maven-metadata.xml (301 B at 2.7 kB/s)
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/plugins/maven-metadata.xml (14 kB at 120 kB/s)
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/com/dianping/maven/plugins/maven-metadata.xml (812 B at 7.1 kB/s)
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/codehaus/mojo/maven-metadata.xml
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/jvnet/hudson/tools/maven-metadata.xml (705 B at 1.6 kB/s)
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/codehaus/mojo/maven-metadata.xml (21 kB at 44 kB/s)
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml (981 B at 2.0 kB/s)
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:3.2.1:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:3.2.1:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- maven-archetype-plugin:3.2.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /Users/xuyang/workspace/mavenTestProject
[INFO] Parameter: package, Value: com.sankuai
[INFO] Parameter: groupId, Value: com.sankuai
[INFO] Parameter: artifactId, Value: mavenTest
[INFO] Parameter: packageName, Value: com.sankuai
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /Users/xuyang/workspace/mavenTestProject/mavenTest
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.166 s
[INFO] Finished at: 2022-01-11T15:34:31+08:00
[INFO] ------------------------------------------------------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

现在进入到生成的项目文件夹中

cd mavenTest
1

所生成的文件结构如下:

.
└── mavenTest
    ├── pom.xml
    └── src
        ├── main
        │   └── java
        │       └── com
        │           └── sankuai
        │               └── App.java
        └── test
            └── java
                └── com
                    └── sankuai
                        └── AppTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14

使用上面的例子,我们可以知道下面几个关键概念:

文件夹结构 描述
mavenTest 包含 src 文件夹和 pom.xml
src/main/java java 代码文件在包结构下(com/sankuai)。
src/main/test 测试代码文件在包结构下(com/sankuai)。
src/main/resources 包含了属性文件(在上面的例子中,我们需要手动创建这个结构)。

Maven 也创建了一个简单的 Java 源文件和 Java 测试文件。

package com.sankuai;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}
package com.sankuai;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest
    extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp()
    {
        assertTrue( true );
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 2.2.使用IDEA

使用IDEA开发环境可以快速通过图形界面生成Java项目,接下来展示如何使用IDEA生成Maven项目。

1.在新建项目页面选择Maven,并在右侧选择使用archetype

image-20240105125701224

2.点击next,设置项目groupId和artifactId

image-20240105125713865

需要注意的是,我们无需手动输入Name以及Location,输入artifactId时会自动生成。

3.点击next,校验构建清单

image-20240105125726952

4.点击finish完成构建,之后IDEA就会自动构建Java项目了。

image-20240105125741049

# 3.使用Maven打包项目

接下来我们将使用Maven对项目进行打包,我们可以使用以下两种方案对Java项目进行打包

# 3.1.使用命令行打包

1.使用cd命令进入到项目的根路径。

cd mavenTest
1

2.使用package对项目进行打包

mvn clean package
1

参数说明:

clean 是maven内置的生命周期之一,使用maven打包会在项目生成target文件夹,其中用来存放1)被编译之后的class文件,2)打包生成的最终jar文件

package 是maven内置的生命周期之一,用来对项目进行打包生成jar可执行文件

执行之后,会输出一下内容

[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< com.sankuai:mavenTest >------------------------
[INFO] Building mavenTest 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenTest ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenTest ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTestProject/mavenTest/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenTest ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/xuyang/workspace/mavenTestProject/mavenTest/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mavenTest ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTestProject/mavenTest/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mavenTest ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to /Users/xuyang/workspace/mavenTestProject/mavenTest/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mavenTest ---
[INFO] Surefire report directory: /Users/xuyang/workspace/mavenTestProject/mavenTest/target/surefire-reports
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.pom
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.pom (1.7 kB at 3.7 kB/s)
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-providers/2.12.4/surefire-providers-2.12.4.pom
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-providers/2.12.4/surefire-providers-2.12.4.pom (2.3 kB at 10.0 kB/s)
Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.jar
Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.jar (26 kB at 231 kB/s)

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.sankuai.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ mavenTest ---
[INFO] Building jar: /Users/xuyang/workspace/mavenTestProject/mavenTest/target/mavenTest-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.182 s
[INFO] Finished at: 2022-01-11T16:14:39+08:00
[INFO] ------------------------------------------------------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

在根路径下会自动生成target文件夹

.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   │       └── com
│   │           └── sankuai
│   │               └── App.java
│   └── test
│       └── java
│           └── com
│               └── sankuai
│                   └── AppTest.java
└── target
    ├── classes
    │   └── com
    │       └── sankuai
    │           └── App.class
    ├── maven-archiver
    │   └── pom.properties
    ├── maven-status
    │   └── maven-compiler-plugin
    │       ├── compile
    │       │   └── default-compile
    │       │       ├── createdFiles.lst
    │       │       └── inputFiles.lst
    │       └── testCompile
    │           └── default-testCompile
    │               ├── createdFiles.lst
    │               └── inputFiles.lst
    ├── mavenTest-1.0-SNAPSHOT.jar
    ├── surefire-reports
    │   ├── TEST-com.sankuai.AppTest.xml
    │   └── com.sankuai.AppTest.txt
    └── test-classes
        └── com
            └── sankuai
                └── AppTest.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

其中mavenTest-1.0-SNAPSHOT.jar就是项目打包生成的可执行文件,其中-1.0-SNAPSHOT是项目的版本号信息。

# 3.2.使用IDEA

1.可在IDEA右侧边栏上找到Maven菜单

image-20240105125757609

2.分别双击clean和package按钮就会在当前项目中生成target文件,整个流程比命令行更方便。

image-20240105125811313


# 2. 依赖管理

# 一、创建一个maven项目

官方文档:

  • Maven依赖管理详解 (opens new window)
  • Maven依赖管理最佳实践 (opens new window)
  • Jar包管理方式推荐 (opens new window)

# 1.使用Idea创建一个maven项目

  • File>New>Project,
  • 左侧选择Maven,右侧选择Project SDK为1.8,点击Next
  • 输入项目GroupId、ArtifactId,点击Next
  • 点击Finish

# 2.项目目录结构

image-20240105125824759

# 3.pom文件

<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.sankuai</groupId>
  <artifactId>mavenTest1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mavenTest1</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 二、约定优于配置

# 1.项目目录结构遵循约定

创建的maven空项目已经包含了一定的目录结构,需要开发者遵循这种目录约定,这是使用maven简洁配置需要付出的代价。

目录 说明
{project.basedir} 存放pom文件和项目子模块
{project.basedir}/src/main/java 源码目录
{project.basedir}/src/main/resources 资源目录
{project.basedir}/src/test/java 测试源码目录
{project.basedir}/src/test/resources 测试资源目录
${project.basedir}/target 包输出目录
${project.basedir}/target/classes 编译输出目录
${project.basedir}/target/test-classes 测试编译输出目录

# 三、POM文件

# 1.说明

POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建、声明项目依赖。

# 2.简单配置

  • <?xml>: xml头信息,定义xml文档的版本和编码方式。
  • : 所有pom.xml的根元素,声明了pom相关的命名空间和xsd元素。
  • : 指定当前pom模型的版本,对于maven2/3,只能是4.0.0。
  • : 定义当前maven项目隶属的实际项目。
  • : 定义实际项目中的一个maven模块/项目。
  • : 定义maven项目当前所处的版本
  • groupId\artifactId\version: 定义了一个项目基本的坐标。

# 3.其他配置

  • 项目依赖
  • 插件
  • 执行目标
  • 项目构建profile

# 四、MAVEN坐标

# 1.说明

Maven定义了一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识。 Maven坐标元素包括groupId, artifactId, version, packaging, classifier。

# 2.坐标元素

  • groupId: 定义当前maven项目隶属的实际项目。
  • artifactId: 定义实际项目中的一个maven模块/项目。
  • version: 定义maven项目当前所处的版本。
  • packaging: 定义maven项目的打包方式。打包方式与生成构件的文件扩展名对应,默认为jar, 常用的打包方式有jar, war, pom。
  • classifier: 帮助定义构建输出的附属构件。附属构件与主构件对应。如demo1-1.0-SNAPSHOT-sources.jar这个构件,包含了主构件的源代码。不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是通过附加插件帮助生成的。

# 3.项目构件的文件名

  • 一般规则为: artifactId-version[-classifier].packaging

# 五、MAVEN依赖

# 1.使用maven怎么引入依赖?

  • 如果要引入第三方jar包,需要知道jar的坐标,然后放入pom.xml中的dependencies元素中。 示例如下:

      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
    1
    2
    3
    4
    5
    6
    7
    8
  • dependencies元素包含多个dependency,每个dependency代表项目依赖的一个构件信息。

  • dependency元素中的 groupId, artifactId,version定义了一个构件的基本坐标。

  • type被依赖构件的类型,对应于被依赖构件的packaging。默认为jar, 表示被依赖的构件是一个jar包。

  • scope表示依赖的范围,参考下文 2.maven依赖范围。

  • optional表示依赖是否可选,参考可选依赖。

  • exclusions用来排除传递依赖。

# 2.maven依赖范围

依赖范围就是用来控制依赖与三种classpath(编译classpath,运行classpath,测试classpath【编译测试代码、运行测试代码】)的关系。

  • compile: 编译依赖范围。如果未指定,默认使用该依赖范围。对于编译、测试、运行3种classpath都有效。比如spring-web。

  • test: 测试依赖范围。只对测试classpath有效,在编译主代码、运行项目时无法使用此依赖。比如JUnit。

  • provided: 已提供依赖范围。对于编译、测试classpath有效,但在运行时无效。比如servlet-api,在运行项目的时候容器已经提供了。

  • runtime: 运行时依赖范围。对于测试、运行classpath有效,但在编译主代码时无效。比如jdbc驱动实现,运行的时候才需要具体的jdbc驱动实现。

  • system: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显示指定依赖文件的路径。建议谨慎使用。

    <dependency>
      <groupId>com.john</groupId>
      <artifactId>rt</artifactId>
      <version>1.8</version>
      <scope>system</scope>
      <systemPath>${java.home}/lib/rt.jar</systemPath>
    </dependency>
    
    1
    2
    3
    4
    5
    6
    7
  • import: 导入依赖范围。在maven依赖和dependencyManagement时候用到。

# 3.依赖范围与classpath的关系

依赖范围** **(scope) 对于编译classpath有效 对于测试classpath有效 对于运行classpath有效 举例
compile Y Y Y spring-web
test -- Y -- JUnit
provided Y Y -- servlet-api
runtime -- Y Y JDBC驱动实现
system Y Y -- 本地的jar包

# 4.scope与运行classpath

scope如果对于运行范围有效,是指依赖的jar包会被打包到项目的运行包中,最后运行的时候会被添加到classpath中运行。 如果scope对于运行项目无效,那么项目打包的时候,这些依赖不会被打包到运行包中。

# 六、传递性依赖

# 1.说明

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
1
2
3
4
5
6
7
8
  • 在项目中引入junit,查看项目依赖,发现项目又依赖org.hamcrest:hamcrest-core:1.3,该依赖也被自动加进来,这个叫做依赖的传递。
  • 假设A依赖于B,B依赖于C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,而A对于C是传递性依赖。
  • 第一直接依赖的范围和第二直接依赖的范围决定了传递依赖的范围。

# 2.依赖范围对传递性依赖的影响

第一直接依赖\第二直接依赖 compile test provided runtime
compile compile -- -- runtime
test test -- -- test
provided provided -- provided provided
runtime runtime -- -- runtime

# 七、依赖调解

# 1.第一原则:路径近者优先。

  • A->B->C->Y(1.0),A->D->Y(2.0),Y的2.0版本距离A更近一些,所以maven会选择2.0

# 2.第二原则:第一声明者优先。

  • A->B->Y(1.0),A->D->Y(2.0),Y的1.0版先声明,所以maven会选择1.0版本。

# 八、可选依赖

A->B, scope:compile B->X, scope:compile,optional:true B->Y, scope:compile,optional:true

  • X、Y是可选依赖,依赖不会由B传至A。X、Y不会对A造成影响。
  • 理想情况下,不应该使用可选依赖。

# 九、依赖管理最佳实践

# 1.排除依赖

  • 前提

    A->B, scope:compile B->C, scope:compile

  • 目的:A不想引入传递性依赖C

  • 使用exclusions元素声明排除依赖,exclusions元素可以包含多个exclusion元素。

  • 声明exclusion元素时只需要groupId和artifactId

# 2.归类依赖

  • 使用properties元素定义maven属性

    <properties>
      <springframework.version>5.2.1.RELEASE</springframework.version>
    </properties>
    
    1
    2
    3

# 3.优化依赖

  • 查看当前项目的已解析依赖(Resolved Dependency)

    mvn dependency:list
    
    1
    [INFO] Scanning for projects...
    [INFO] 
    [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
    [INFO] Building mavenTest1 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ mavenTest1 ---
    [INFO] 
    [INFO] The following files have been resolved:
    [INFO]    junit:junit:jar:3.8.1:test
    [INFO] 
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.355 s
    [INFO] Finished at: 2022-01-12T17:11:56+08:00
    [INFO] ------------------------------------------------------------------------
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  • 查看当前项目的依赖树

    mvn dependency:tree
    
    1
    [INFO] Scanning for projects...
    [INFO] 
    [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
    [INFO] Building mavenTest1 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ mavenTest1 ---
    [INFO] com.sankuai:mavenTest1:jar:1.0-SNAPSHOT
    [INFO] \- junit:junit:jar:3.8.1:test
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  0.856 s
    [INFO] Finished at: 2022-01-12T17:12:30+08:00
    [INFO] ------------------------------------------------------------------------
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
  • 分析当前项目的依赖

    mvn dependency:analyze
    
    1
    [INFO] Scanning for projects...
    [INFO] 
    [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
    [INFO] Building mavenTest1 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] >>> maven-dependency-plugin:2.8:analyze (default-cli) > test-compile @ mavenTest1 >>>
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenTest1 ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTest1/src/main/resources
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenTest1 ---
    [INFO] Changes detected - recompiling the module!
    [INFO] Compiling 1 source file to /Users/xuyang/workspace/mavenTest1/target/classes
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mavenTest1 ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTest1/src/test/resources
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mavenTest1 ---
    [INFO] Changes detected - recompiling the module!
    [INFO] Compiling 1 source file to /Users/xuyang/workspace/mavenTest1/target/test-classes
    [INFO] 
    [INFO] <<< maven-dependency-plugin:2.8:analyze (default-cli) < test-compile @ mavenTest1 <<<
    [INFO] 
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:analyze (default-cli) @ mavenTest1 ---
    [INFO] No dependency problems found
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  1.902 s
    [INFO] Finished at: 2022-01-12T17:13:05+08:00
    [INFO] ------------------------------------------------------------------------
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

# 3. 仓库

# 一、引入

  • maven坐标和依赖是一个构件在maven世界中的逻辑表示方式,而构件的物理表示方式是文件。
  • maven通过仓库来统一管理这些构件。
  • maven项目将不再各自存储其依赖文件,只需要声明依赖坐标。
  • maven采用引用的方式将依赖的jar引入进来,不对真实的jar进行拷贝,但是打包的时候,运行需要用到的jar都会被拷贝到安装包

# 二、仓库分类

  • 本地仓库
  • 远程仓库: 中央仓库、私服、其他公共仓库

# 1.本地仓库

  • 在安装maven后本地仓库并不存在,当我们执行第一条maven命令的时候才会创建本地仓库。

  • 默认情况下,maven本地仓库默认地址是~/.m2/respository目录,

  • 用户可以自定义本地仓库目录,在~/.m2/settings.xml文件中进行修改

  • 下载构件:从远程仓库下载到本地仓库目录中

  • 使用本地项目构件:将本地项目构件安装到maven本地仓库

    mvn clean install
    
    1

# 2.远程仓库

  • 本地仓库不存在构件时,需要从远程仓库下载构件。

# 3.中央仓库

  • 在maven的超级pom中可以看到默认的中央仓库。

    • 超级pom:所有maven项目都会继承,其中的配置会自动继承。

    • 超级pom所在文件:${M2_HOME}/lib/maven-model-builder-3.6.3.jar

    • 解压jar文件

    • 查看lib/org/apache/maven/model/pom-4.0.0.xml

    • 找到中央仓库的默认配置:

      <repositories> 
        <repository> 
          <id>central</id>
          <name>Central Repository</name>
          <url>https://repo.maven.apache.org/maven2</url>
          <layout>default</layout>
          <snapshots> <!-- 不从该中央仓库下载快照版本的构件 -->
            <enabled>false</enabled>
          </snapshots>
        </repository>
      </repositories>
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
  • 默认的中央仓库:

    • https://repo.maven.apache.org/maven2/ (opens new window)

# 4.私服

  • 私服是一种特殊的远程仓库,是架设在局域网内的仓库服务。
  • 私服代理广域网上的远程仓库,供局域网内的maven用户使用。
  • 私服的好处:
    • 节省自己的外网带宽。
    • 加速maven构建。
    • 部署第三方构件。
    • 提高稳定性,增强控制。
    • 降低中央仓库的负荷。

# 5.其他远程仓库

  • 公司的远程仓库:http://pixel.sankuai.com/
  • 美团的Settings:Settings.xml (opens new window)

# 三、远程仓库配置

# 1.在项目POM中配置远程仓库(项目)

  1. 说明:该配置只对当前项目有效。

  2. 配置信息

    <repositories>
      <repository>
        <id>meituan-dianping-releases</id>
        <name>Repository for releases artifacts</name>
        <url>http://pixel.sankuai.com/repository/group-releases</url>
        <snapshots>
          <enabled>false</enabled>
        </snapshots>
      <releases>
        <enabled>true</enabled>
        <updatePolicy>always</updatePolicy>
      </releases>
      </repository>
    
      <repository>
        <id>meituan-dianping-snapshots</id>
        <name>Repository for snapshots artifacts</name>
        <url>http://pixel.sankuai.com/repository/group-snapshots</url>
        <snapshots>
          <enabled>true</enabled>
          <updatePolicy>always</updatePolicy>
        </snapshots>
        <releases>
          <enabled>false</enabled>
        </releases>
      </repository>
    </repositories>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
  3. repositories->repository元素说明

    • repositories元素下可以使用repository子元素声明一个或多个远程仓库。
    • id:远程仓库标识,id名称唯一。注意:maven自带的中央仓库id为central,如果其他的仓库声明也使用该id,会覆盖中央仓库的配置。
    • url:远程仓库地址。
    • releases:用来控制对于发布版本构件的下载。
      • enabled属性表示是否开启发布版本的下载支持。
      • updatePolicy:用来配置maven从远程仓库更新的频率。
        • 默认为daily,表示每天检查一次。
        • never,从不检查更新。
        • always,每次构建都检查更新。
        • interval: X,每隔X分钟检查更新一次(X为任意整数)
      • checksumPolicy:用来配置maven检查校验和文件的策略。
        • 默认为warn,执行构建时给出警告信息。
        • fail,遇到校验和错误,就让构建失败。
        • ignore,让maven完全忽略校验和错误。
    • snapshots:用来控制对于快照版本构件的下载。
      • enabled属性表示是否开启快照版本的下载支持。
      • 快照版本的构件以-SNAPSHOT结尾,发布版本没有这个标识。
    • layout:default表示仓库的布局是maven2或者maven3的默认布局,而不是maven1的布局。
  4. 测试远程仓库能否正常拉取依赖

    • 以项目mavenTest1为例。

        <dependencies>
          <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
          </dependency>
        </dependencies>
      
      1
      2
      3
      4
      5
      6
      7
    • 首先,删除${localRepository}/org/projectlombok/lombok目录文件,此时本地仓库无依赖。

    • 切换到项目目录,在终端执行mvn compile

    • 查看终端输出。

      [INFO] Scanning for projects...
      [INFO] 
      [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
      [INFO] Building mavenTest1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/projectlombok/lombok/1.18.16/lombok-1.18.16.pom
      Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/projectlombok/lombok/1.18.16/lombok-1.18.16.pom (1.5 kB at 4.0 kB/s)
      Downloading from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/projectlombok/lombok/1.18.16/lombok-1.18.16.jar
      Downloaded from meituan-dianping: http://pixel.sankuai.com/repository/mtdp/org/projectlombok/lombok/1.18.16/lombok-1.18.16.jar (1.9 MB at 2.8 MB/s)
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenTest1 ---
      [INFO] Using 'UTF-8' encoding to copy filtered resources.
      [INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTest1/src/main/resources
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenTest1 ---
      [INFO] Nothing to compile - all classes are up to date
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time:  3.726 s
      [INFO] Finished at: 2022-01-12T19:05:58+08:00
      [INFO] ------------------------------------------------------------------------
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
    • 观察Downloading from meituan-dianping后面就是在pom文件中配置的远程仓库,meituan-dianping是定义的仓库id。 在本地仓库缺少依赖后,就会从配置的远程仓库下载依赖。

# 2.在用户配置中配置镜像仓库(全局)

  1. 说明:该配置对所有使用该配置的项目都有效。

  2. 什么是镜像仓库?

    • 如果仓库X可以提供仓库Y所有的内容,那么就可以认为X是Y的一个镜像。
    • 任何一个可以从Y获取的构件,都可以从它的镜像中获取。
    • 可以采用镜像的方式配置远程仓库,镜像在settings.xml中进行配置,对所有使用该配置的maven项目起效。
  3. 配置镜像仓库

        <mirrors>
            <mirror>
                <id>meituan-dianping</id>
                <name>meituan-dianping mirror</name>
                <url>http://pixel.sankuai.com/repository/mtdp</url>
                <mirrorOf>*</mirrorOf>
            </mirror>
        </mirrors>
    
    1
    2
    3
    4
    5
    6
    7
    8
  4. 配置解释

    • mirrors元素下包含多个mirror子元素,每个mirror元素表示一个远程镜像。
    • id:镜像id,唯一标识。
    • name:镜像名称。
    • url:镜像地址
    • mirrorOf:指定哪些远程仓库的id使用这个镜像去下载构件,这个对应pom.xml文件中repository元素的id。就是表示这个镜像是给哪些pom.xml文件中的远程仓库使用的,这里面需要列出远程仓库的id,多个之间用逗号隔开。
    • mirrorOf配置语法:
      • * :匹配所有远程仓库。
      • external: * :匹配所有不在本机上的远程仓库。
      • repo1, repo2 :匹配仓库repo1和repo2,多个仓库之间使用逗号分割。
      • *, !repo1 :匹配所有远程仓库,除了仓库repo1,使用感叹号(!)将仓库从匹配中排除。
  5. 注意 镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,maven无法自动切换到被镜像仓库,因此将会无法下载构件。

  6. 结合私服使用 由于私服可以代理所有远程仓库(包含中央仓库),因此对于组织内部的maven用户来说,使用一个私服地址就等于使用了所有需要的外部仓库。

# 四、仓库布局

  1. 仓库布局方式 任何一个构件都有其唯一的坐标,根据坐标可以定义其在仓库中的唯一路径。

  2. 举例

    • 以spring-web的依赖为例

    • 项目demo1 pom文件的依赖

      org.springframework spring-web 5.2.1.RELEASE

    • 查看spring-web的jar包在本地仓库中的位置。

      • /Users/xuyang/.m2/repository/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar
      • /Users/xuyang/.m2/repository是本地仓库目录。
      • 构件的目录路径为groupId/artifactId/version/
      • 构件名称为:artifactId-version[-classifier].packaging, packaging默认为jar。
  3. maven如何定位构件路径

    1. 将groupId中的句点分隔符(.)转换成路径分隔符(/),同时在后面追加一个路径分隔符(/)。
      • org.springframework--->org/springframework/
    2. 将artifactId拼接在1的路径上, 同时在后面追加一个路径分隔符(/)。
      • org/springframework/spring-web/
    3. 将version拼接在2的路径上,同时在后面追加一个路径分隔符(/)。
      • org/springframework/spring-web/5.2.1.RELEASE/
    4. 将构件名称拼接在3的路径上。
      • org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar

# 五、仓库如何解析依赖

  1. 当本地仓库没有依赖构件的时候,maven会自动从远程仓库下载;
  2. 当依赖版本为快照版本的时候,maven会自动找到最新的快照。
  3. 依赖解析机制:
    • 依赖范围是system的时候,maven直接从本地文件系统解析构件。
    • 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如发现相应构件,则解析成功。
    • 如果本地仓库构件不存在,并且依赖的版本是显示的发布版本构件,则遍历所有的远程仓库,发现后 下载并解析使用。

# 六、仓库检索

  1. Sonatype(中央仓库):https://search.maven.org/ (opens new window)
  2. Sonatype Nexus: https://repository.sonatype.org/ (opens new window)
  3. MVNRepository:https://mvnrepository.com/ (opens new window)

# 4. 私服

# 一、私服

公司私服为自研,详情需查看官方文档:Pixel PRFAQ v1 (opens new window)

# 二、使用

# 1.安装和配置

  1. 安装Maven工具,配置环境变量及本地仓库(自行Google一下)
  2. 使用公司统一的settings.xml文件替换本地的settings.xml文件(一般是在.m2目录下),如果本部门或者bg/bu有特殊需求,比如到家等,请使用本部门自己的settings.xml文件(// TODO 总结一下内部在用的)
    1. 公司统一的settings.xml文件:统一的settings.xml文件 (opens new window)
    2. 到家事业部等需要使用线下仓库隔离(其它部门不要使用)的:线下 Maven Settings.xml (opens new window)
  3. (可选)idea请做如下配置,选择.m2文件下的settings.xml文件和本地仓库目录,并在后面勾选上覆盖

# 2.上传(deploy)配置

  • Plus上配置Maven发布项

链接:1. Quick Start (New) (opens new window)

链接(仅到家或其它使用offline仓库的部门使用):6. Maven部署线下仓库 (opens new window)

  • Plus上Maven发布项相关配置说明

链接:3. Maven 参数 (opens new window)

  • 个人本地deploy配置

目前在逐步封禁本地deploy限制推进 (opens new window),请使用Plus进行发包


# 5. 生命周期和插件

# 一、maven的生命周期

# 1.生命周期介绍

  • maven的生命周期就是为了对所有的构建过程进行抽象和统一。
  • 包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建步骤。
  • 几乎所有的项目构建,都能映射到这样一个生命周期上。

# 2.生命周期详解

# 2.1.三套生命周期

  • maven包含三套相互独立的生命周期。
  • clean生命周期:用于清理项目。
  • default生命周期:用于构建项目。
  • site生命周期:用于建立项目站点。

# 2.2.生命周期内部的阶段

  • 每个生命周期包含多个阶段(phase)。
  • 这些阶段是有序的。
  • 后面的阶段依赖于前面的阶段。当执行某个阶段的时候,会先执行它前面的阶段。
  • 用户和maven最直接的交互就是调用这些生命周期阶段。

# 2.3.clean生命周期

clean生命周期的目的是清理项目,它包含3个阶段:

clean生命周期阶段 说明
pre-clean 执行一些clean前需要完成的工作
clean 清理上一次构建生成的文件
post-clean 执行一些clean后需要完成的工作

# 2.4.default生命周期

default生命周期的目的是构建项目,它定义了真正构建时所需要完成的所有步骤,是所有生命周期中最核心的部分。 包含23个阶段:详细介绍 (opens new window)

default生命周期阶段 说明
validate 验证项目是否正确并且所有必要信息都可用
initialize 初始化构建状态,比如设置属性值、创建目录
generate-sources 生成包含在编译阶段中的任何源代码
process-sources 处理源代码,比如说,过滤任意值
generate-resources 生成将会包含在项目包中的资源文件
process-resources 复制和处理资源到目标目录,为打包阶段最好准备
compile 编译项目的源代码
process-classes 处理编译生成的文件,比如说对Java class文件做字节码改善优化
generate-test-sources 生成包含在编译阶段中的任何测试源代码
process-test-sources 处理测试源代码,比如说,过滤任意值
generate-test-resources 为测试创建资源文件
process-test-resources 复制和处理测试资源到目标目录
test-compile 编译测试源代码到测试目标目录
process-test-classes 处理测试源码编译生成的文件
test 使用合适的单元测试框架运行测试 , 测试代码不会被打包或部署
prepare-package 在实际打包之前,执行任何的必要的操作为打包做准备
package 将编译后的代码打包成可分发的格式,比如JAR
pre-integration-test 在执行集成测试前进行必要的动作。比如说,搭建需要的环境
integration-test 如有必要,将程序包处理并部署到可以运行集成测试的环境中
post-integration-test 执行集成测试完成后进行必要的动作。比如说,清理集成测试环境
verify 运行任何检查以验证包是否有效并符合质量标准
install 安装项目包到maven本地仓库,供本地其他maven项目使用
deploy 将最终包复制到远程仓库,供其他开发人员和maven项目使用

# 2.5.site生命周期

site生命周期的目的是建立和发布项目站点。 Maven能够基于pom.xml所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。 包含以下4个阶段:

site生命周期阶段 说明
pre-site 执行一些在生成项目站点之前需要完成的工作
site 生成项目站点文档
post-site 执行一些在生成项目站点之后需要完成的工作
site-deploy 将生成的项目站点发布到服务器上

# 2.6.mvn命令和生命周期

从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。 需要注意的是,每套生命周期是相互独立的,但是每套生命周期的阶段是有前后依赖关系的。

  • 格式: mvn 阶段 [阶段2] ...[阶段n]
  • mvn clean:该命令调用clean生命周期的clean阶段。
    • 实际执行的阶段为clean生命周期中的pre-clean和clean阶段。
  • mvn test:该命令调用default生命周期的test阶段。
    • 实际执行的阶段为default生命周期的从validate到test的所有阶段。
    • 这也就解释了为什么执行测试的时候,项目的代码能够自动编译。
  • mvn clean install:该命令调用clean生命周期的clean阶段和default生命周期的install阶段。
    • 实际执行的阶段为clean生命周期的pre-clean、clean阶段,以及default生命周期的从validate到install的所有阶段。
  • mvn clean deploy:该命令调用clean生命周期的clean阶段和default生命周期的deploy阶段。
    • 实际执行的阶段为clean生命周期的pre-clean、clean阶段,以及default生命周期的所有阶段。
    • 包含了清理上次构建的结果、编译代码、运行单元测试、打包、将打好的包安装到本地仓库、将打好的包发布到远程仓库等所有操作。

# 二、maven插件

# 1.插件目标

  • maven的核心仅仅定义了抽象的生命周期,具体的任务交给插件完成。
    • 每套生命周期包含多个阶段,每个阶段执行什么操作,都由插件完成。
  • 插件以独立的构件形式存在。
    • 为了能够复用代码,每个插件包含多个功能。
    • 插件中的每个功能就叫做插件的目标(Plugin Goal),每个插件中可能包含一个或者多个插件目标(Plugin Goal)。

# 2.插件绑定

  • maven生命周期的阶段与插件目标绑定,以完成某个具体的构件任务。
    • 比如项目编译这个任务,对应了default生命周期阶段的compile阶段,而maven-compiler-plugin插件的compile目标能够完成该任务,因此将他们进行绑定,实现项目编译任务。
  • 生命周期阶段与插件进行绑定后,可以通过mvn 阶段来执行和这个阶段绑定的插件目标。

# 3.内置绑定

# 3.1.说明

为了让用户几乎不用任何配置就能构建maven项目,maven为一些主要的生命周期阶段绑定好了插件目标,当我们通过命令调用生命周期阶段时,绑定的插件目标就会执行对应的任务

# 3.2.clean生命周期阶段与插件目标的绑定关系

生命周期阶段 插件目标 作用
pre-clean
clean maven-clean-plugin:clean 删除项目的输出目录
post-clean

# 3.3.default生命周期阶段与插件目标的绑定关系(打包类型:jar)

生命周期阶段 插件目标 作用
process-resources maven-resources-plugin:resources 复制主资源文件到主输出目录
compile maven-compiler-plugin:compile 编译主代码到主输出目录
process-test-resources maven-resources-plugin:testResources 复制测试资源文件到测试输出目录
test-compile maven-compiler-plugin:testCompile 编译测试代码到测试输出目录
test maven-surefire-plugin:test 执行测试用例
package maven-jar-plugin:jar 创建项目jar包
install maven-install-plugin:install 将项目输出构件安装到本地maven仓库
deploy maven-deploy-plugin:deploy 将项目输出构件部署到远程仓库
  • 关于输出目录,参考Maven学习2: 依赖管理 - 2.约定优于配置 (opens new window)

# 3.4.site生命周期阶段与插件目标的绑定关系

生命周期阶段 插件目标 作用
pre-site
site maven-site-plugin:site 生成项目站点
post-site
site-deploy maven-site-plugin:deploy 将项目站点部署到远程服务器

# 3.5.构建过程验证

  • 与1.2生命周期详解中6.mvn命令和生命周期示例相同,项目依然使用mavenTest1作为示例。

  • mvn clean:

    [INFO] Scanning for projects...
    [INFO] 
    [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
    [INFO] Building mavenTest1 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenTest1 ---
    [INFO] Deleting /Users/xuyang/workspace/mavenTest1/target
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  0.276 s
    [INFO] Finished at: 2022-01-12T19:34:03+08:00
    [INFO] ------------------------------------------------------------------------
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  • mvn test:

    • 调用default生命周期的test阶段,实际执行的时候 default生命周期的validate阶段直到test阶段都要执行,每个阶段绑定的插件目标也会被执行。可以看到处理资源、编译源码、处理测试资源、编译测试源码、测试插件目标都得到了执行。
    [INFO] Scanning for projects...
    [INFO] 
    [INFO] -----------------------< com.sankuai:mavenTest1 >-----------------------
    [INFO] Building mavenTest1 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenTest1 ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTest1/src/main/resources
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenTest1 ---
    [INFO] Nothing to compile - all classes are up to date
    [INFO] 
    [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mavenTest1 ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory /Users/xuyang/workspace/mavenTest1/src/test/resources
    [INFO] 
    [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mavenTest1 ---
    [INFO] Changes detected - recompiling the module!
    [INFO] Compiling 1 source file to /Users/xuyang/workspace/mavenTest1/target/test-classes
    [INFO] 
    [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mavenTest1 ---
    [INFO] Surefire report directory: /Users/xuyang/workspace/mavenTest1/target/surefire-reports
    
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running com.sankuai.AppTest
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.006 sec
    
    Results :
    
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  2.026 s
    [INFO] Finished at: 2022-01-12T19:34:57+08:00
    [INFO] ------------------------------------------------------------------------
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
  • mvn clean install:

    • 该命令调用clean生命周期的clean阶段和default生命周期的install阶段。
    • (构建过程内容省略)
  • mvn clean deploy:

    • 该命令调用clean生命周期的clean阶段和default生命周期的deploy阶段。
    • (构建过程内容省略)

# 4.插件配置

# 4.1.命令行插件配置

  • 在maven命令中使用-D参数,并伴随一个参数键=参数值的形式,来配置插件目标的参数。
  • 参数-D是java自带的,其功能是通过命令行设置一个java系统属性。
  • 例如,跳过执行测试目标,mvn clean pakcage -Dmaven.test.skip=true

# 4.2.pom文件中插件全局配置

  • 用户在pom文件声明插件时,可以对插件进行全局的配置。

  • 例如,配置maven-compiler-plugin编译Java 1.8版本的源文件,生成与JVM 1.8兼容的字节码文件。

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <!-- 编译器版本 -->
                    <compilerVersion>1.8</compilerVersion>
                    <!-- 源码版本 -->
                    <source>1.8</source>
                    <!-- 目标代码版本 -->
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

# 5.获取插件信息

# 5.1.在线插件信息

  • Apache:Maven Plugins (opens new window)
  • 可以查看插件介绍、插件目标、目标参数等等。

# 5.2.使用 maven-help-plugin 描述插件

  • 使用 maven-help-plugin 获取插件信息。

  • 方式1:使用插件坐标:mvn help:describe -Dplugin=groupId:artifactId:version

  • 方式2:使用插件目标前缀:mvn help:describe -Dplugin=Goal Prefix,目标前缀的作用是方便在命令行直接运行插件。

  • 如果要获取插件的详细描述,可以在命令后加上-Ddetail参数。

  • 举例:两种方式获取maven-compiler-plugin:3.8.1的插件描述信息

    • mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:3.8.1

    • mvn help:describe -Dplugin=compiler

    • 过程输出

      [INFO] org.apache.maven.plugins:maven-compiler-plugin:3.2
      
      Name: Apache Maven Compiler Plugin
      Description: The Compiler Plugin is used to compile the sources of your
        project.
      Group Id: org.apache.maven.plugins
      Artifact Id: maven-compiler-plugin
      Version: 3.2
      Goal Prefix: compiler
      
      This plugin has 3 goals:
      
      compiler:compile
        Description: Compiles application sources
      
      compiler:help
        Description: Display help information on maven-compiler-plugin.
          Call mvn compiler:help -Ddetail=true -Dgoal=<goal-name> to display
          parameter details.
      
      compiler:testCompile
        Description: Compiles application test sources.
      
      For more information, run 'mvn help:describe [...] -Ddetail'
      
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time:  1.950 s
      [INFO] Finished at: 2022-01-12T19:39:20+08:00
      [INFO] ------------------------------------------------------------------------
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31

# 5.3.从命令行调用插件

  • maven命令帮助:mvn -h
  • 输出:usage: mvn [options] [<goal(s)>] [<phase(s)>]
  • 获取项目依赖树:mvn dependency:tree
  • 分析当前项目依赖:mvn dependency:analyze
  • 查看当前项目的已解析依赖:mvn dependency:list
  • 查看项目最终pom.xml文件:mvn help:effective-pom

# 6.插件解析

maven简化了插件的使用和配置,但是具体maven是怎么解析插件的呢?

# 6.1.插件仓库

  • 与依赖构件一样,插件构件同样基于坐标存储在maven仓库中。在需要的时候,maven会从本地仓库查找插件,如果不存在,则从远程仓库查找。找到后下载到本地仓库使用。

  • 配置插件仓库,插件仓库与依赖构件仓库是分开配置的。

  • 在项目pom文件pluginRepositories -> pluginRepository元素中配置插件仓库。

  • 具体配置(maven 内置的插件远程仓库):

    <pluginRepositories>
      <pluginRepository>
        <id>central</id>
        <name>Central Repository</name>
        <url>https://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
          <enabled>false</enabled>
        </snapshots>
        <releases>
          <updatePolicy>never</updatePolicy>
        </releases>
      </pluginRepository>
    </pluginRepositories>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

# 6.2.插件的默认groupId

  • org.apache.maven.plugins,配置时不建议省略。

# 6.3.解析插件版本

  • maven在超级pom中为所有核心插件定义了版本。
  • 使用插件时候,应该一直显式设定版本。

# 6.4.解析插件前缀

  • 插件前缀(Goal Prefix)与groupId:artifactId是一一对应的,这种对应关系存储在仓库元数据中。

    • 示例:匹配关系 (opens new window)

    • 本地仓库插件元数据文件位置:~/.m2/repository/org/apache/maven/plugins/maven-metadata-central.xml

      <metadata>
          <plugins>
              <plugin>
                  <name>Apache Maven Clean Plugin</name>
                  <prefix>clean</prefix>
                  <artifactId>maven-clean-plugin</artifactId>
              </plugin>
              <plugin>
                  <name>Apache Maven Compiler Plugin</name>
                  <prefix>compiler</prefix>
                  <artifactId>maven-compiler-plugin</artifactId>
              </plugin>
          </plugins>
      </metadata>
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
  • 默认的插件仓库groupId:org.apache.maven.plugins

  • 配置自己的插件仓库元数据:

    • 用户的maven配置文件:~/.m2/settings.xml

    • settings -> pluginGroups -> pluginGroup元素中配置。

      <settings>
        <pluginGroups>
          <pluginGroup>com.your.plugins</pluginGroup>
        </pluginGroups>
      </settings>
      
      1
      2
      3
      4
      5

# 6. 多执行环境

# 一、灵活构建

# 1.三大特性

  • 属性
  • 资源过滤
  • Profile

# 2.属性

# 2.1.自定义属性

  • 用户可以在项目的pom文件的元素中自定义maven属性。

  • 在pom文件的其他地方,使用${属性名称}引用该属性。

  • 意义在于消除重复,示例代码如下。

    <project>
        <properties>
            <springframework.groupId>org.springframework</springframework.groupId>
            <springframework.version>5.2.1.RELEASE</springframework.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>${springframework.groupId}</groupId>
                <artifactId>spring-web</artifactId>
                <version>${springframework.version}</version>
            </dependency>
            <dependency>
                <groupId>${springframework.groupId}</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${springframework.version}</version>
            </dependency>
        </dependencies>
    </project>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

# 2.2.内置属性

两个常用的内置属性:

  • ${basedir}: 项目根目录,即包含pom文件的目录
  • ${version}: 项目版本

# 2.3.POM属性

用户可以使用该类属性引用pom文件中对应元素的值。 常用的pom属性如下:

  • ${project.build.sourceDirectory}: 项目的主源码目录,默认为src/main/java/
  • ${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/
  • ${project.build.directory}:项目的构建输出目录,默认为target/
  • ${project.outputDirectory}: 项目的主代码编译输出目录,默认为target/classes/
  • ${project.testOutputDirectory}: 项目的测试代码编译输出目录,默认为target/test-classes/
  • ${project.groupId}: 项目的groupId
  • ${project.artifactId}: 项目的artifactId
  • ${project.version}: 项目的版本,与${version}等价。
  • ${project.build.finalName}: 项目打包输出文件的名称。默认为${project.artifactId}-${project.version}

# 2.4.settings属性

用户可以使用该类属性引用settings文件中对应元素的值。

  • ${settings.localRepository}:用户本地仓库

# 2.5.Java系统属性

  • 所有Java系统属性都可以使用Maven属性引用。
  • 使用mvn help:system查看所有的Java系统属性。
  • ${user.home}:用户目录

# 2.6.环境变量属性

  • 所有环境变量都可以使用env.开头的Maven属性引用。
  • 使用mvn help:system查看所有的环境变量属性。
  • ${env.JAVA_HOME}: JAVA_HOME环境变量的值。

# 3.资源过滤

# 3.1.遇到的问题

  • 多环境配置:项目不同的环境对应着不同的数据库配置,手动更改这些配置往往比较低效。

# 3.2.解决

  1. 使用maven属性将这些会发生变化的部分提取出来。
  2. 然后开启资源目录的过滤功能,就可以解决这一问题。

# 3.3.示例

  • 数据库配置

    # src/main/resources/application.properties

    database.jdbc.driverClass=${db.driver}
    database.jdbc.connectionUrl=${db.url}
    database.jdbc.username=${db.user}
    database.jdbc.password=${db.pw}
    
    1
    2
    3
    4
  • 开启资源过滤

    <project>    
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>jdbc:mysql//localhost:3306/test</db.url>
            <db.user>dev-user</db.user>
            <db.pw>dev-pwd</db.pw>
        </properties>
    
        <build>
            <resources>
                <resource>
                    <directory>${project.basedir}/src/main/resources</directory>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    </project>    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  • 编译代码mvn compile

    • 查看主代码编译输出目录下的资源文件,已经得到了替换。
    database.jdbc.driverClass=com.mysql.jdbc.Driver
    database.jdbc.connectionUrl=jdbc:mysql//localhost:3306/test
    database.jdbc.username=aaa
    database.jdbc.password=aaa-pwd
    
    1
    2
    3
    4

# 4.Maven Profile

# 4.1.针对不同环境的profile

  • 示例:基于开发和测试环境的profile

        <project>    
        <profiles>
            <profile>
                <id>dev</id>
                <properties>
                    <db.driver>com.mysql.jdbc.Driver</db.driver>
                    <db.url>jdbc:mysql//localhost:3306/test</db.url>
                    <db.user>dev</db.user>
                    <db.pw>dev-pwd</db.pw>
                </properties>
            </profile>
    
            <profile>
                <id>test</id>
                <properties>
                    <db.driver>com.mysql.jdbc.Driver</db.driver>
                    <db.url>jdbc:mysql//localhost:3306/test</db.url>
                    <db.user>test</db.user>
                    <db.pw>test-pwd</db.pw>
                </properties>
            </profile>
        </profiles>
    </project>    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

# 4.2.激活profile

  1. 命令行激活

    • 使用maven命令行参数 -P 加上profile的 id ,多个id之间逗号分隔
    • 如:mvn clean compile -Pdev
  2. 默认激活

    • 配置profile > activation > activationByDefault元素的值为true,该profile默认激活

      <project>    
          <profiles>
              <profile>
                  <id>dev</id>
                  <activation>
                      <activeByDefault>true</activeByDefault>
                  </activation>
                  <properties>
                      <db.driver>com.mysql.jdbc.Driver</db.driver>
                      <db.url>jdbc:mysql//localhost:3306/test</db.url>
                      <db.user>dev</db.user>
                      <db.pw>dev-pwd</db.pw>
                  </properties>
              </profile>
          </profiles>
      </project>    
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
  3. 系统属性激活

    • mvn ... -D属性xx=属性xx的值

    • 指定的属性存在,激活profile

    • 指定的属性存在,并且值等于x时,激活profile

      <project>    
          <profiles>
              <profile>
                  <id>dev</id>
                  <activation>
                      <property>
                          <name>test</name>
                          <value>x</value>
                      </property>
                  </activation>
                  <properties>
                      <db.driver>com.mysql.jdbc.Driver</db.driver>
                      <db.url>jdbc:mysql//localhost:3306/test</db.url>
                      <db.user>dev</db.user>
                      <db.pw>dev-pwd</db.pw>
                  </properties>
              </profile>
          </profiles>
      </project>    
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
  4. 文件存在与否激活

    <project>    
        <profiles>
            <profile>
                <id>dev</id>
                <activation>
                    <file>
                        <exists>x.properties</exists>
                        <missing>y.properties</missing>
                    </file>
                </activation>
                <properties>
                    <db.driver>com.mysql.jdbc.Driver</db.driver>
                    <db.url>jdbc:mysql//localhost:3306/test</db.url>
                    <db.user>dev</db.user>
                    <db.pw>dev-pwd</db.pw>
                </properties>
            </profile>
        </profiles>
    </project>    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

# 4.3.查看当前激活的profile

  • mvn help:active-profiles

# 4.4.列出所有的profile

  • mvn help:all-profiles

# 7. 项目多模块 一、Maven聚合

# 1.为什么使用聚合?

假设一个项目包含两个模块,我们想要一次构建两个模块,而不是到两个模块的目录下分别执行mvn命令,这时就需要用到聚合。

# 2.聚合配置

# 2.1.聚合模块pom配置

  • 聚合模块packaging类型为 pom

  • 聚合模块包含 modules元素,每个module对应一个要被聚合的子模块。

  • module的值是当前pom的相对目录。

  • 具体配置

    <modules>
        <module>模块1</module>
        <module>模块2</module>
        <module>模块3</module>
    </modules>
    
    1
    2
    3
    4
    5

# 2.2.聚合模块相对位置

  • 通常将聚合模块放在项目目录的最顶层,其他模块作为聚合模块的子目录。

# 2.3.聚合模块意义

  • 聚合模块仅仅是帮助聚合其他模块构建的工具,本身并无实质内容。
  • 解决同时构建多个模块的问题。

# 2.4.聚合模块构建

  • maven首先会解析聚合模块的pom,分析要构建的模块,并计算出一个反应堆构建顺序(Reactor Build Order),然后根据这个顺序依次构建各个模块。

# 二、Maven继承

# 1.为什么使用继承?

解决重复配置问题。

# 2.继承配置

# 2.1.项目继承的配置

  • 父模块的packaging类型为pom。

  • 子模块需要配置project -> parent元素信息

    • 父模块坐标配置,groupId:artifactId:version
    • relativePath: 父模块pom文件所在路径,默认父pom在上一层目录下(即 ../pom.xml)。
    • 构建过程中,maven会根据relativePath检查父pom,如果找不到,再从本地仓库查找。
  • 子模块继承父模块的配置

    <parent>
        <groupId>父构件groupId</groupId>
        <artifactId>父构件artifactId</artifactId>
        <version>父构件的版本号</version>
        <relativePath>父构件pom.xml路径</relativePath>
    </parent>
    
    1
    2
    3
    4
    5
    6

# 2.2.可继承的pom元素

  • groupId:项目组ID,项目坐标的核心元素。
  • version:项目版本,项目坐标的核心元素。
  • description:项目的描述信息。
  • organization:项目的组织信息。
  • inceptionYear:项目的创始年份。
  • url:项目的url地址。
  • developers:项目的开发者信息。
  • contributors:项目的贡献者信息。
  • distributionManagement:项目的部署配置信息。
  • issueManagement:项目的缺陷跟踪系统信息。
  • ciManagement:项目的持续集成系统信息。
  • scm:项目的版本控制系统信息。
  • mailingLists:项目的邮件列表信息。
  • properties:自定义的maven属性配置信息。
  • dependencyManagement:项目的依赖管理配置。
  • repositories:项目的仓库配置。
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等信息。
  • reporting:包括项目的报告输出目录配置、报告插件配置等信息。

# 2.3.依赖管理

  • maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性.

  • 在dependencyManagement元素下的依赖声明不会引入实际的依赖,但是它能约束对dependencies下的依赖使用。

  • import依赖范围:

    • 将目标pom中dependencyManagement配置导入,并合并到当前项目的dependencyManagement元素中。

    • 不想使用继承的方式,来达到使用目标pom中的依赖的目的。

    • import依赖范围一般都指向打包类型为pom的模块。

      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>targetGroupId</groupId>
                  <artifactId>targetArtifactId</artifactId>
                  <version>targetVersion</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
              <dependency>构件1</dependency>
              <dependency>构件2</dependency>
          </dependencies>
      </dependencyManagement>
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13

# 2.4.插件管理

  • maven中提供了dependencyManagement来帮助管理依赖继承,也提供了pluginManagement元素帮助管理插件继承。

  • 在父模块pom中该元素的配置不会造成实际的插件调用行为,只有在子pom.xml中配置plugins -> plugin元素声明该插件的时候,插件才会起效。

  • 子pom插件中只需要写groupId、artifactId,其他信息都可以从父pom中传递过来。

  • 举例,使用maven-source-plugin插件生成项目源码包,将该插件的jar-no-fork目标绑定到default生命周期的verify阶段。

    • 父pom插件管理配置

      <build>
          <pluginManagement>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-source-plugin</artifactId>
                      <version>3.2.1</version>
                      <executions>
                          <execution>
                              <id>attach-source</id>
                              <phase>verify</phase>
                              <goals>
                                  <goal>jar-no-fork</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
              </plugins>
          </pluginManagement>
      </build>
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
    • 子pom插件声明配置

      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-source-plugin</artifactId>
              </plugin>
          </plugins>
      </build>
      
      1
      2
      3
      4
      5
      6
      7
      8

# 三、聚合与继承

# 1.目的

  • 聚合主要是为了方便快速构建多模块项目。
  • 继承主要是为了消除重复配置。

# 2.与其他模块关系

  • 对于聚合模块来说,聚合模块知道有哪些被聚合的模块,而被聚合模块不知道聚合模块的存在。
  • 对于继承来说,父模块是不知道有哪些子模块继承它,而子模块需要使用parent来引用父模块。

# 3.共同点

  • 聚合模块和继承中的父模块的packaging属性都必须是pom类型的。
  • 同时,聚合模块和父模块除了pom.xml,一般都没有实际内容。

# 4.实际使用

  • 将聚合和继承一起使用,能同时使用到两者的优点。

# 四、反应堆

# 1.介绍

# 1.1.反应堆

  • 在多模块的maven项目中,反应堆(Reactor)是指所有模块组成的一个构建结构。

# 1.2.单模块项目的反应堆

  • 就是该模块本身。

# 1.3.多模块项目的反应堆

  • 包含模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序。

# 2.反应堆构建顺序

  • maven按聚合配置中的顺序读取pom。
  • 如果该pom没有依赖模块,那么就构建该模块,否则就先构建其依赖的模块,如果该依赖还依赖于其他模块,则进一步先构建依赖的依赖。

# 3.裁剪反应堆

# 3.1.说明

  • 一般情况下,用户会选择构建整个项目或者选择构建单个模块。
  • 如果想要仅仅构建完整反应堆中的某些模块,就需要实时的裁剪反应堆

# 3.2.裁剪反应堆选项

  • 执行mvn -h可以看到裁剪反应堆的选项。
  • -am:--also-make, 同时构建所列模块的依赖模块。
  • -amd:-also-make-dependencies,同时构建依赖于所列模块的模块。
  • -pl:--projects ,构建指定的模块,模块之间使用逗号分隔
  • -rf:-resume-from ,从指定的模块继续反应堆
编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19
maven
阿里是如何进行单元测试的

← maven 阿里是如何进行单元测试的→

最近更新
01
spark基础
02-22
02
mysql读写分离和分库分表
02-22
03
数据库迁移
02-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式