Maven项目构建
# Maven 项目构建
# 目录结构
让我们来看一下功能的划分:
# Maven 项目生命周期与构建原理
# Maven 三大项目生命周期
- 默认构建生命周期 (Default Lifeclyle): 该生命周期表示这项目的构建过程,定义了一个项目的构建要经过的不同的阶段。
- 清理生命周期 (Clean Lifecycle): 该生命周期负责清理项目中的多余信息,保持项目资源和代码的整洁性。一般拿来清空 target 目录下的文件。
- 站点管理生命周期 (Site Lifecycle) : 向我们创建一个项目时,我们有时候需要提供一个站点,来介绍这个项目的信息,如项目介绍,项目进度状态、项目组成成员,版本控制信息,项目javadoc索引信息等等。站点管理生命周期定义了站点管理过程的各个阶段。
# Maven 对项目默认生命周期的抽象
Maven根据一个项目的生命周期的每个阶段,将一个项目的生命周期抽象成了如上图所示的 23 个阶段。而每一个阶段应该干什么事情由用户决定。换句话说 maven 为每一个阶段设计了接口,你可以为每一阶段自己定义一个接口,进而实现对应阶段应该有的行为。
在经历这些生命周期的阶段中,每个阶段会理论上会有相应的处理操作。但是,在实际的项目开发过程中, 并不是所有的生命周期阶段都是必须的。 基于类似的约定,maven 默认地为一些不同类型的 maven 项目生命周期的阶段实现了默认的行为。
Maven 在设计上将生命周期阶段的抽象和对应阶段应该执行的行为实现分离开,maven 这些实现放到了插件中,这些插件本质上是实现了maven留在各个生命周期阶段的接口。 如下图所示,maven 针对不同打包类型的 maven 项目的生命周期阶段绑定了对应的默认行为:
# Maven 各生命阶段行为绑定
maven会根据 Mojo 功能的划分,将具有相似功能的 Mojo 放到一个插件中。并且某一个特定的 Mojo 能实现的功能称为 goal,即目标,表明该Mojo能实现什么目标。
例如,我们项目生命周期有两个阶段: compile 和 test-compile,这两阶段都是需要将Java源代码编译成class文件中,相对应地,compile和test-compiler分别被绑定到了org.apache.maven.plugin.compiler.CompilerMojo 和org.apache.maven.plugin.compiler.TestCompilerMojo上:
# 依赖原则
# 依赖路径最短优先原则
A -> B -> C -> X(1.0)
A -> D -> X(2.0)
2
由于 X(2.0) 路径最短,所以使用 X(2.0)。
# 声明顺序优先原则
A -> B -> X(1.0)
A -> C -> X(2.0)
2
在 POM 中最先声明的优先,上面的两个依赖如果先声明 B,那么最后使用 X(1.0)。
# 覆写优先原则
子 POM 内声明的依赖优先于父 POM 中声明的依赖。
# 解决依赖冲突
找到 Maven 加载的 Jar 包版本,使用 mvn dependency:tree
查看依赖树,根据依赖原则来调整依赖在 POM 文件的声明顺序。
# 项目中依赖的搜索顺序
# 依赖仓库的配置方式
maven 项目使用的仓库一共有如下几种方式:
- 中央仓库,这是默认的仓库
- 镜像仓库,通过 sttings.xml 中的 settings.mirrors.mirror 配置
- 全局 profile 仓库,通过 settings.xml 中的 settings.repositories.repository 配置
- 项目仓库,通过 pom.xml 中的 project.repositories.repository 配置
- 项目 profile 仓库,通过 pom.xml 中的 project.profiles.profile.repositories.repository 配置
- 本地仓库
如果所有配置都存在,依赖的搜索顺序就会变得异常复杂。
# 分析依赖搜索顺序
先从最简单开始,慢慢增加配置,查看有什么变化。
# 准备测试环境
安装 jdk、maven。并使用如下命令创建测试项目:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=true -DgroupId=com.pollyduan -DartifactId=myweb -Dversion=1.0 -Dpackage=com.pollyduan
创建完成后,为了避免后续测试干扰,先执行一次 compile。
cd myweb
mvn compile
2
最后,修改 pom.xml 文件,将 junit 版本号改为 4.12 。我们要使用这个 jar 来测试依赖的搜索顺序。
# 默认情况
首先确保 junit4.12 不存在:
rm -rf ~/.m2/repository/junit/junit/4.12
默认情况下没有配置任何仓库,也就是说,既没改 $M2_HOME/conf/settings.xml 也没有添加~/.m2/settings.xml
执行编译,查看日志中拉取 junit 的仓库。
mvn compile
...
Downloaded from central: https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.pom (24 kB at 11 kB/s)
2
3
4
可以看出,默认是从 central 中央仓库拉取的 jar.
# 配置镜像仓库 settings_mirror
创建~/.m2/setttings.xml ,内容如下:
<settings>
<mirrors>
<mirror>
<id>settings_mirror</id>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
2
3
4
5
6
7
8
9
重新测试:
rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile
2
在日志中查看下载依赖的仓库:
Downloaded from settings_mirror: https://maven.aliyun.com/repository/public/junit/junit/4.12/junit-4.12.pom (24 kB at 35 kB/s)
- 可以看出,是从 settings_mirror 中下载的 jar
- 结论:settings_mirror 的优先级高于 central
# 配置 pom 中的仓库 pom_repositories
在 project 中增加如下配置:
<repositories>
<repository>
<id>pom_repositories</id>
<name>local</name>
<url>http://10.18.29.128/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
2
3
4
5
6
7
8
9
10
11
12
13
- 由于我们改变了 id 的名字,所以仓库地址无所谓,使用相同的地址也不影响测试。
执行测试:
rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile
2
在日志中查看下载依赖的仓库:
Downloaded from pom_repositories: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 95 kB/s)
从显示的仓库 id 可以看出:
- jar 是从 pom_repositories 中下载的。
- pom_repositories 优先级高于 settings_mirror
# 配置全局 profile 仓库 settings_profile_repo
在~/.m2/settings.xml 中 settings 的节点内增加:
<profiles>
<profile>
<id>s_profile</id>
<repositories>
<repository>
<id>settings_profile_repo</id>
<name>netease</name>
<url>http://mirrors.163.com/maven/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
执行测试:
rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Ps_profile
2
在日志中查看下载依赖的仓库:
Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 63 kB/s)
从显示的仓库 id 可以看出:
- jar 是从 settings_profile_repo 中下载的。
- settings_profile_repo 优先级高于 settings_mirror。
- settings_profile_repo 优先级高于 pom_repositories 。
# 配置项目 profile 仓库 pom_profile_repo
<profiles>
<profile>
<id>p_profile</id>
<repositories>
<repository>
<id>pom_profile_repo</id>
<name>local</name>
<url>http://10.18.29.128/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
执行测试:
rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Ps_profile,p_profile
mvn compile -Pp_profile,s_profile
2
3
在日志中查看下载依赖的仓库:
Downloaded from settings_profile_repo: http://mirrors.163.com/maven/repository/maven-public/junit/junit/4.12/junit-4.12.pom (24 kB at 68 kB/s)
从显示的仓库 id 可以看出:
- jar 是从 settings_profile_repo 中下载的
- settings_profile_repo 优先级高于 pom_profile_repo
进一步测试:
rm -rf ~/.m2/repository/junit/junit/4.12
mvn compile -Pp_profile
2
在日志中查看下载依赖的仓库:
Downloaded from pom_profile_repo: http://10.18.29.128/nexus/content/groups/public/junit/junit/4.12/junit-4.12.pom (24 kB at 106 kB/s)
从显示的仓库 id 可以看出:
- jar 是从 settings_profile_repo 中下载的
- pom_profile_repo 优先级高于 pom_repositories
# 最后确认 local_repo 本地仓库~/.m2/repository
这不算测试了,只是一个结论,可以任意测试。
- 只要
~/.m2/repository
中包含依赖,无论怎么配置,都会优先使用 local 本地仓库中的 jar.
# 最终结论
- settings_mirror 的优先级高于 central
- settings_profile_repo 优先级高于 settings_mirror
- settings_profile_repo 优先级高于 pom_repositories
- settings_profile_repo 优先级高于 pom_profile_repo
- pom_profile_repo 优先级高于 pom_repositories
- pom_repositories 优先级高于 settings_mirror
通过上面的比较得出完整的搜索链:
local_repo > settings_profile_repo > pom_profile_repo > pom_repositories > settings_mirror > central
# 参考
- https://blog.csdn.net/luanlouis/article/details/50492163
- https://maven.org.cn/guides/index.html
- https://my.oschina.net/polly/blog/2120650