Maven技术分享
Maven技术分享
Maven 基本说明
Maven说明背景
由于有少许人对Maven不了解,或者其他人对Maven只是一个简单的认识,所以这里增加Maven基本说明,给大家了解Maven的一些特性,以便在今后的开发有更多的理解和启发。
Maven简介
Maven是一个项目的管理和综合工具,他提供了开发人员构建一个完整项目的生命周期框架。在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作,同时创建报表,检查,构建和测试自动化设置。它的设置都很简单,并且可重复使用,让开发人员的工作更轻松。概括地说,Maven简化和标准化了项目创建的过程。处理 编译,分配,文档,团队协作和其他任务的无缝连接。
总之,Maven是一种创新的软件项目管理工具,提供了一个项目对象模型(POM)文件的新概念来管理项目的构建、相关性和文档。他最强大的功能就是能够自动下载项目依赖库。
Maven目标(Goal)
Maven中有有一个比较重要的概念,就是目标(Goal):表示一个特定的、对构建和管理工程有帮助的任务。它可能绑定了 0 个或多个构建阶段。没有绑定任何构建阶段的目标可以在构建生命周期之外被直接调用执行。对goal的一个定义可以是:
- 项目是可重复使用,易维护,更容易理解的一个综合模型。
-
插件或交互的工具,这种声明性的模式
针对这种,在特定phase执行对工程有帮助的任务的功能,使得我们能够使用它的一些特性(比如使用Maven原生的插件)和加入一些自定义的动作(基于Maven开发自定义的插件),为我们的开发提供多样性的功能。
例如:mvn clean dependency:copy-dependencies package,执行mvn clean package时,可以直接调用某个构建过程中未被绑定的阶段任务,这里的操作是利用dependency插件的goal:copy-dependencies将项目所有依赖jar包归档到classpath(~/target/classes/)
Maven安装配置
Maven的安装包括Linux环境下,和Windows环境下,具体安装和说明这里忽略。
这里需要注意的是用户配置文件:settings.xml,包含了众多的客户化配置,需要各位重点关注。
Maven资源库
Maven资源库,顾名思义,就是Maven存放资源文件的地方,根据存放位置,他有以下几种资源库:
Maven本地资源库
Maven中央仓库 http://search.maven.org/ 或者 http://mvnrepository.com/
Maven和Eclipse
不管是官方Eclipse,还是公司自研的Eclipse都已经集成了Maven,我们可以直接使用工具去创建一个Maven项目。依托Eclipse集成工具,我们可以对项目进行可视化编译、构建、测试、打包、校验、安装、发布等等操作过程。我们不仅可以使用这些操作,可以看到操作中反应的日志,可以得到最终构建的结果。总之很方便,当然,也可以自己本地尝试。
Maven项目结构
上面说了,Maven是基于对象模型(POM)文件来构建项目的,而他另外的组成还包括src/main/java,src/main/resources,src/test/java,src/test/resources的maven标准文件结构。
结构:
Maven生命周期
生命周期其实就是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序。Maven标准生命周期包括:
- clean (包括pre-clean clean post-clean)
- default(or build)
-
site
其中clean为默认的清除操作,以下列出主要的构建生命周期:
生命周期阶段
|
描述
|
---|---|
validate | 检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到。 |
initialize | 初始化构建状态,例如设置属性。 |
generate-sources | 生成编译阶段需要包含的任何源码文件。 |
process-sources | 处理源代码,例如,过滤任何值(filter any value)。 |
generate-resources | 生成工程包中需要包含的资源文件。 |
process-resources | 拷贝和处理资源文件到目的目录中,为打包阶段做准备。 |
compile | 编译工程源码。 |
process-classes | 处理编译生成的文件,例如 Java Class 字节码的加强和优化。 |
generate-test-sources | 生成编译阶段需要包含的任何测试源代码。 |
process-test-sources | 处理测试源代码,例如,过滤任何值(filter any values)。 |
test-compile | 编译测试源代码到测试目的目录。 |
process-test-classes | 处理测试代码文件编译后生成的文件。 |
test | 使用适当的单元测试框架(例如JUnit)运行测试。 |
prepare-package | 在真正打包之前,为准备打包执行任何必要的操作。 |
package | 获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。 |
pre-integration-test | 在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量。 |
integration-test | 处理和部署必须的工程包到集成测试能够运行的环境中。 |
post-integration-test | 在集成测试被执行后执行必要的操作。例如,清理环境。 |
verify | 运行检查操作来验证工程包是有效的,并满足质量要求。 |
install | 安装工程包到本地仓库中,该仓库可以作为本地其他工程的依赖。 |
deploy | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程。 |
注意:
- 当一个阶段通过 Maven 命令调用时,例如 mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行!
- 当连续多个阶段一起执行时,将会按照规定的生命周期顺序,挨个执行。
Maven管理依赖
Maven依赖说明
Maven 核心特点之一是依赖管理。一旦我们开始处理多模块工程(包含数百个子模块或者子工程)的时候,模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法:依赖管理(dependencyManagerment),依赖(dependencies)。
Maven-Project(A) Maven-Solution-Project (包含Solution-Parent) Solution-Parent
+_ dependency B (B项目依赖了log4j、netty、junit) +_ dependency Maven-Project(A) +_ dependencyManagerment
+_ dependency C (C项目依赖了xmlpull、jface、项目D) +_ dependencyManagerment +_ dependency log4j 1.0
+_ dependency D (C项目依赖了很多第三方jar包) +_ dependency 项目D +_ dependency netty 1.0
+_ dependency junit 1.0
+_ dependency xmlpull 1.0
+_ dependency jface 1.0
传递依赖发现
项目中会出现这种情形:项目A依赖于B,项目C依赖于项目A,那么C也会依赖到B。这种机制是通过读取工程文件(pom.xml)中的依赖项,Maven 可以找出工程之间的依赖关系。但如果项目结构越发庞大,项目间依赖也势必复杂。针对这种情况,Maven提供了一些功能去控制可递增的依赖。
功能
|
功能描述
|
---|---|
依赖覆盖 | 决定当多个手动创建的版本同时出现时,哪个依赖版本将会被使用。 如果两个依赖版本在依赖树里的深度是一样的时候,第一个被声明的依赖将会被使用。 |
依赖管理 | 直接的指定手动创建的某个版本被使用。例如当一个工程 C 在自己的以来管理模块包含工程 B,即 B 依赖于 A, 那么 A 即可指定在 B 被引用时所使用的版本。 |
依赖范围 | 包含在构建过程每个阶段的依赖。 |
依赖排除 | 任何可传递的依赖都可以通过 “exclusion” 元素被排除在外。举例说明,A 依赖 B, B 依赖 C,因此 A 可以标记 C 为 “被排除的”。 |
依赖可选 | 任何可传递的依赖可以被标记为可选的,通过使用 “optional” 元素。例如:A 依赖 B, B 依赖 C。因此,B 可以标记 C 为可选的, 这样 A 就可以不再使用 C。 |
依赖范围
我们对项目中的一些依赖,可以限定他的作用范围,使它在特定的执行阶段去执行。
范围
|
描述
|
---|---|
编译阶段 | 该范围表明相关依赖是只在工程的类路径下有效。默认取值。 |
供应阶段 | 该范围表明相关依赖是由运行时的 JDK 或者 网络服务器提供的。 |
运行阶段 | 该范围表明相关依赖在编译阶段不是必须的,但是在执行阶段是必须的。 |
测试阶段 | 该范围表明相关依赖只在测试编译阶段和执行阶段。 |
系统阶段 | 该范围表明你需要提供一个系统路径。 |
导入阶段 | 该范围只在依赖是一个 pom 里定义的依赖时使用。同时,当前工程的POM 文件的 部分定义的依赖关系可以取代某特定的 POM。 |
Maven依赖管理
海外的项目结构中,有一系列的业务工程,应用平台和依赖的父项目,父项目的pom文件包含所有的公共的依赖关系,我们称其为其他子工程的父项目。
如下,核心系统依赖层次图:
Maven项目打包
移至另外一篇文章《Shell插件打包说明》
Maven项目发布
Maven项目发布本身并不复杂,只是在集成到系统项目迭代和版本管理上面相对复杂。整体的发布流程就是,触发项目的发布命令,执行Maven生命周期中的deploy阶段的goal,做资源编译以及收集,并且按照pom文件约定的插件流程,默认生成jar包,并且上传到私服的对应位置。
上传的位置,依据pom文件或者用户settings文件中约定的releases和snapshots文件路径,将项目上传上去。
例如:项目test-1.0.0-RELEASE项目,groupId:cn.sunline.odc artifactId:test version:1.0.0-RELEASE url:http://nexus.odc.sunline.cn/repository/old-odc-public
对其进行deploy,则会上传jar包到约定私服地址:http://nexus.odc.sunline.cn/repository/old-odc-public/cn/sunline/odc/test/1.0.0-RELEASE/test-1.0.0-RELEASE.jar