Maven的生命周期是对项目所有的构建过程进行抽象和统一。它包含了项目的清理、初始化、编译、测试、打包、部署和站点生成等构建步骤。Maven的生命周期本质是定义项目构建的各个步骤,它本身是抽象的,并不作任何的具体工作,而是将构建过程中的各个步骤任务交个相对应的插件来完成。这使得Maven的生命周期具有良好的扩展性,开发者可以自己编写插件实现代码绑定到构建的某个步骤。当然,在绝大部分场景下,开发者不必这样来做,因为Maven初始为项目构建的各个步骤绑定了默认的插件。
生命周期
Maven有三个相互独立的生命周期。它们分别是Clean Lifecycle
Default Lifecycle
Site Lifecycle
。
1. Maven生命周期
生命周期 Maven有三个相互独立的生命周期。它们分别是:
每个独立的生命周期都包含一些阶段(phase),这些阶段是一个有序的组合,后面的阶段依赖于前面的阶段。Maven主要的生命周期阶段在下表中已用加粗字体标出。 Clean生命周期
Default生命周期
Site生命周期
命令行命令 Maven执行项目构建的过程实质上是调用Maven生命周期阶段的过程。Maven主要的生命周期阶段并不多,其命令行命令几乎都是基于这些阶段的简单组合。而且Maven的大三生命周期是相互独立的,每个生命周期的阶段都有前后依赖的关系。任何一个简单的或组合的命令,只有当前面的阶段执行成功,后面的阶段才有机会得以继续执行。如果前面的某个阶段执行失败,后面的阶段就会被短路而导致无法继续执行下去。
因此,执行该命令最终达到的效果是: 生命周期内置绑定的插件 Maven的生命周期是抽象的,它本身不做任何具体的工作,项目构建的过程实质是调用Maven生命周期阶段的过程,而Maven初始已经为生命周期的大部分阶段绑定了默认的插件,当外部调用Maven生命周期阶段的时候,绑定到这些阶段的插件就会来执行对应的具体工作。 Clean生命周期内置绑定的插件(详见Lifecycles Reference)
Default生命周期内置绑定的插件(详见Plugin Bindings for default Lifecycle Reference)
Site生命周期内置绑定的插件(详见Lifecycles Reference)
项目打包类型与生命周期内置绑定的插件 Maven项目的打包类型是由
2. Maven Super POM
倘若Maven安装的目录用{MAVEN_HOME}来表示,那么,Maven Super POM文件所在的路径为: Super POM 的作用
3. Maven发布构件到私服
创建角色 在Nexus3管理控制台中,创建一个具有 创建用户 在Nexus3管理控制台中,创建一个用作构件部署的账户,并将刚刚创建的角色分配给该用户: settings.xml配置 在maven的用户或全局
pom.xml配置 在项目的 注:如果项目是快照版本(项目pom.xml配置文件中version的值含有
部署构件 在命令行中执行命令: 如果部署的构件是一个快照版本,由于存储快照版本的仓库是允许构件重新部署的,因此快照版本的构件在每次发布时都会自动带上一个时间戳标记,以作为区分和历史备份。如图所示: 4. Maven仓库
本地仓库和远程仓库的关系 远程仓库又分为:中央仓库(https://repo.maven.apache.org/maven2)、私服(如Nexus OSS)、其他第三方公共库(如阿里http://maven.aliyun.com/nexus/content/groups/public) 大部分构件最初都是Maven从远程仓库下载回来存储到本地仓库的(也有一小部分是通过安装命令直接安装到本地仓库的),一旦Maven从远程仓库下载一个构件回来并存储到了本地仓库,只要你不手工删除该构件,同一个版本号的构件永远不需要去远程仓库下载第二次。因为Maven在构建项目查找依赖的构件时都首先会在本地仓库中去查找,如果在本地仓库查找不到才会去远程仓库中查找。一旦Maven在本地仓库查找到了依赖所需的构件,就不会再去远程仓库中去查找和下载了。 Maven本地仓库配置 在maven的用户或全局的
Maven远程仓库配置 方式一,在maven的用户或全局的
方式二,在项目的 配置结构和在settings.xml中的结构一致。其区别在于,一个是在maven配置文件中配置,一个是在项目pom文件中配置。如果是针对某个或几个项目,可选择方式二来配置。 Maven仓库检索顺序 接下来做一个实验,在maven的用户或全局的 然后在项目的 然后在命令行中执行命令: 命令执行时输出的日志信息: 可以看到,maven在下载依赖所需的构件时检索仓库的顺序依次为(仓库ID):nexus-maven-snapshots → nexus-maven-releases → nexus-maven-3rd.party → fanlychie-maven-repo → central 这是第二次构建项目时输出的信息,可以看到,在第一次构建成功后,再次构建项目的时候就不会再去远程仓库下载构件了。 5. Maven镜像
在maven的用户或全局的
Maven在构建项目的时候,每当一个构件在本地仓库中查找不到时,它就会去远程中央仓库(central,Super POM中声明使用的远程仓库地址)中去下载。如果某个镜像的 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
每个独立的生命周期都包含一些阶段(phase),这些阶段是一个有序的组合,后面的阶段依赖于前面的阶段,并且顺序执行各个阶段。
Clean生命周期
阶段 | 描述 |
---|---|
pre-clean | 在实际项目清理之前执行所需的过程 |
clean | 删除上一个版本生成的所有文件 |
post-clean | 执行完成项目清理所需的过程 |
Default生命周期
阶段 | 描述 |
---|---|
validate | 验证项目所有必要的信息都是可用的 |
initialize | 初始化构建状态,例如设置属性或创建目录 |
generate-sources | 生成包含在编译中的源代码 |
process-sources | 处理源代码,过滤和替换一些变量的值 |
generate-resources | 生成包含在包中的资源 |
process-resources | 处理资源包,将其复制到目标目录 |
compile | 编译项目的源代码 |
process-classes | 从编译中对生成的文件进行后处理,例如对Java类进行字节码增强 |
generate-test-sources | 生成包含在编译中的测试源代码 |
process-test-sources | 处理源代码,过滤和替换一些变量的值 |
generate-test-resources | 生成包含在测试包中的资源 |
process-test-resources | 处理资源包,将其复制到测试目标目录 |
test-compile | 编译项目的测试源代码 |
process-test-classes | 从编译中对生成的测试文件进行后处理,例如对Java类进行字节码增强 |
test | 执行单元测试,测试代码不会被打包部署 |
prepare-package | 打包之前执行所需的任何操作 |
package | 打包项目 |
pre-integration-test | 集成测试前执行的操作,如设置环境等 |
integration-test | 执行集成测试,如果需要,可将软件包部署到可以运行集成测试的环境 |
post-integration-test | 集成测试后执行的操作,如清理环境 |
verify | 检查软件包是否符合标准 |
install | 将项目输出构件安装到本地仓库 |
deploy | 将项目输出构件部署到远程仓库 |
Site生命周期
阶段 | 描述 |
---|---|
pre-site | 在实际项目站点生成之前执行所需的过程 |
site | 生成项目的站点文档 |
post-site | 执行完成站点生成所需的进程,并准备站点部署 |
site-deploy | 将生成的站点文档部署到指定的Web服务器 |
命令行命令与生命周期
$ mvn clean package
该命令会调用执行Clean生命周期的clean和clean之前的所有阶段,以及会调用Default生命周期的package和package之前的所有阶段。
所有maven模块(项目)的POM(Project Object Model,项目对象模型)都隐式的继承了Super POM。Super POM中定义了一组标准的配置变量。maven模块(项目)的POM会自动继承这些配置变量,你可以在maven模块(项目)的POM文件中直接使用它们,或者通过重新声明以覆盖它们。
倘若Maven安装的目录用{MAVEN_HOME}来表示,那么,Maven Super POM文件所在的路径为:{MAVEN_HOME}/lib/maven-model-builder-3.5.4.jar/org/apache/maven/model/pom-4.0.0.xml
4.0.0
central
Central Repository
https://repo.maven.apache.org/maven2
default
false
central
Central Repository
https://repo.maven.apache.org/maven2
default
false
never
${project.basedir}/target
${project.build.directory}/classes
${project.artifactId}-${project.version}
${project.build.directory}/test-classes
${project.basedir}/src/main/java
${project.basedir}/src/main/scripts
${project.basedir}/src/test/java
${project.basedir}/src/main/resources
${project.basedir}/src/test/resources
maven-antrun-plugin
1.3
maven-assembly-plugin
2.2-beta-5
maven-dependency-plugin
2.8
maven-release-plugin
2.5.3
${project.build.directory}/site
release-profile
performRelease
true
true
maven-source-plugin
attach-sources
jar-no-fork
true
maven-javadoc-plugin
attach-javadocs
jar
true
maven-deploy-plugin
true
Super POM 的作用
定义了一个ID为central
的远程仓库(url
即为这个仓库的地址),如果没有其它特殊的声明,maven模块(项目)所需要的构件(jar包等)都会到这个远程中央仓库中去下载;
定义了一个插件仓库,这个插件仓库和上面定义的远程仓库用的是同一个仓库,maven模块(项目)所需要的插件包都会到这个远程中央仓库中去下载;
定义了一组标准的配置变量,在maven模块(项目)的POM中可以通过${project.build.XX}
来使用它们,如 ${project.build.directory};
${project.basedir}/target
${project.build.directory}/classes
${project.artifactId}-${project.version}
${project.build.directory}/test-classes
${project.basedir}/src/main/java
${project.basedir}/src/main/scripts
${project.basedir}/src/test/java
以Nexus3搭建的Maven私服为例子,用管理员账户登录系统,并在管理控制台的配置面板中创建一个用于发布项目构件(在maven中,所有的依赖、插件、项目构建的输出,都可以称作是构件)的账户。
创建角色
在Nexus3管理控制台中,创建一个具有nx-component-upload
和nx-repository-view-*-*-*
两个权限的角色:
创建用户
在Nexus3管理控制台中,创建一个用作构件部署的账户,并将刚刚创建的角色分配给该用户:
settings.xml配置
找到maven的用户或全局settings.xml
配置文件,添加如下代码:
nexus-maven-snapshot
deployment
deployment123
nexus-maven-releases
deployment
deployment123
用于配置连接到远程服务器的账户和密码信息。主要用于发布项目构件上传到maven私服的时进行权限认证。
pom.xml配置
在项目的pom.xml
配置文件中,如果是快照(项目pom.xml文件中version的值含有*-SNAPSHOT
)则添加如下代码:
nexus-maven-snapshots
http://10.10.10.121:8081/repository/maven-snapshots/
如果不是快照(项目pom.xml文件中version的值不含SNAPSHOT
)则添加如下代码:
nexus-maven-releases
http://10.10.10.121:8081/repository/maven-releases/
用于指定当前项目发布到maven私服时上传到哪个仓库中存储。如果是快照文件则使用
元素,否则使用
元素。
这里的值必须要与settings.xml配置文件中
中的
的值匹配,否则在发布构件到maven私服的时候,就会因连接到远程服务器的身份验证失败导致发布构件失败(maven构建的时候报401
错误)。
用于指定当前项目发布到maven私服时上传存储到的那个仓库的地址。
部署构件
在命令行中执行命令:
$ mvn clean deploy
如果部署的构件是一个快照版本,由于存储快照版本的仓库是允许构件重新部署的,因此快照版本的构件在每次发布时都会自动带上一个时间戳标记,以作为区分和历史备份。如图所示:
Maven仓库分为两种,一种是本地仓库,一种是远程仓库。
本地仓库是maven用来在本地机器上存储从远程仓库下载回来的构件的位置。
远程仓库包含了绝大多数流行的开源的java构件,项目依赖的构件一般都可以在这里下载。不同的远程仓库可能包含不同的java构件。
本地仓库和远程仓库的关系
远程仓库又分为:中央仓库(https://repo.maven.apache.org/maven2)、私服(如Nexus OSS)、其他第三方公共库(如阿里的http://maven.aliyun.com/nexus/content/groups/public)。
大部分构件最初都是Maven从远程仓库下载回来存储到本地仓库的(也有一小部分是通过安装命令直接安装到本地仓库的),一旦Maven从远程仓库下载一个构件回来存储到本地仓库,只要你不手工删除该构件,它将永远不需要再下载一次。因为Maven每次查找依赖的构件时都会首先在本地仓库中去查找,然后才是去远程仓库中查找。一旦Maven在本地仓库查找到了依赖所需的构件,就不会再去远程仓库中去查看下载了。
Maven本地仓库配置
找到maven的用户或全局的settings.xml
配置文件,如下:
D:/application/repo/maven
用于指定本地仓库的位置。所有从远程仓库下载回来的构件都存储在这个目录中。
Maven远程仓库配置
settings.xml
配置文件,在
标签中添加如下代码:
... ...
nexus-maven-snapshots
http://10.10.10.121:8081/repository/maven-snapshots/
true
true
nexus-maven-snapshots
http://10.10.10.121:8081/repository/maven-snapshots/
true
true
... ...
用于配置一个远程的可供下载的构件仓库。
则用于配置一个远程的可供下载的插件仓库。
必须是唯一的。
是这个仓库的地址。
pom.xml
配置文件中,添加如下代码:
fanlychie-maven-repo
https://raw.github.com/fanlychie/maven-repo/releases
其效果可等效于在maven的用户或全局的settings.xml
文件中配置的效果。
Maven仓库检索顺序
找到maven的用户或全局的settings.xml
配置文件,在
标签中添加如下代码:
jdk7-development
1.7
true
1.7
1.7
1.7
nexus-maven-snapshots
http://10.10.10.121:8081/repository/maven-snapshots/
true
true
nexus-maven-releases
http://10.10.10.121:8081/repository/maven-releases/
true
false
nexus-maven-3rd.party
http://10.10.10.121:8081/repository/3rd.party/
true
false
nexus-maven-snapshots
http://10.10.10.121:8081/repository/maven-snapshots/
true
true
nexus-maven-releases
http://10.10.10.121:8081/repository/maven-releases/
true
false
nexus-maven-3rd.party
http://10.10.10.121:8081/repository/3rd.party/
true
false
然后在项目的pom.xml
配置文件中,添加如下代码:
fanlychie-maven-repo
https://raw.github.com/fanlychie/maven-repo/releases
org.fanlychie
jexcel
2.2.2
然后在命令行中执行命令:
$ mvn compile
可以看到,maven在下载依赖所需的构件时检索仓库的顺序依次为(仓库ID):nexus-maven-snapshots → nexus-maven-releases → nexus-maven-3rd.party → fanlychie-maven-repo → central
其本质的检索顺序是:本地仓库 → maven用户或全局配置文件settings.xml中的仓库 → 项目pom.xml文件中配置的仓库 → maven超POM中的仓库。
maven在下载依赖所需的构件时,只要一个构件在其中的任意一个仓库中查找到,就不会再继续检索其他的仓库。
这是第二次构建项目时输出的信息,可以看到,在第一次构建成功后,再次构建项目的时候就不会再去远程仓库下载构件了。
如果一个仓库X可以提供仓库Y存储的所有构件,那么就可以称仓库X是仓库Y的一个镜像。由于地理位置等原因,国内网络连接Maven官方的中央仓库网速一般较慢或时常出现网络不稳定的状态,从而导致项目在构建所需的时间较长或失败。使用镜像的好处就是,它往往能提供比中央仓库更快的服务(通常选择地理位置上与自己较近且口碑较好的镜像), 从而提高下载速度, 最终达到提高项目构建效率的目的。
首先我们先找到maven的用户或全局的settings.xml
配置文件,在
标签中添加如下代码:
aliyun-maven-repo
http://maven.aliyun.com/nexus/content/groups/public/
central
用于配置一个镜像。
必须是唯一的。
是镜像的地址。
用于匹配Maven仓库(
)的ID。常见的匹配规则有:
通配符 | 描述 |
---|---|
* | 匹配所有的Maven仓库ID |
repo1,repo2 | 只匹配ID为repo1或repo2的仓库 |
external:* | 匹配除本地仓库之外的所有仓库 |
*,!repo1 | 匹配除ID为repo1之外的所有仓库 |
每当Maven需要去远程仓库下载一个构件时,如果这个仓库被该镜像匹配到,则去这个仓库下载构件的请求就会被该镜像拦截掉,并将此次请求转发到该镜像配置的地址中去下载。