一、Maven的生命周期
- clean:项目清理的处理
- default(或 build):项目部署的处理
- site:项目站点文档创建的处理
build的所有阶段
- validate 验证项目 验证项目是否正确且所有必须信息是可用的
- compile 执行编译 源代码编译在此阶段完成
- Test 测试 使用适当的单元测试框架(例如JUnit)运行测试。
- package 打包 创建JAR/WAR包如在 pom.xml中定义提及的包
- verify 检查 对集成测试的结果进行检查,以保证质量达标
- install 安装 安装打包的项目到本地仓库,以供其他项目使用
- deploy 部署 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程
在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行
二、Maven仓库
- 本地仓库
Maven 的本地仓库,在安装 Maven 后并不会创建,它是在第一次执行 maven 命令的时候才被创建。运行 Maven 的时候,Maven 所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。默认情况下,不管Linux还是 Windows,每个用户在自己的用户目录下都有一个路径名为 .m2/respository/ 的仓库目录。 - 中央仓库
Maven 中央仓库是由 Maven 社区提供的仓库,其中包含了大量常用的库。中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到。 - 远程仓库
如果 Maven 在中央仓库中也找不到依赖的文件,它会停止构建过程并输出错误信息到控制台。为避免这种情况,Maven 提供了远程仓库的概念,它是开发人员自己定制仓库,包含了所需要的代码库或者其他工程中用到的 jar 文件。
三、聚合与继承
- 聚合
Maven的聚合特性能够帮助把项目的各个模块聚合在一起构建,聚合模块的打包方式必须为pom
<groupId>my</groupId>
<artifactId>ALL</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>../A</module>
<module>../B</module>
</modules>
- 继承
Maven的继承特性可以将各个模块相同的依赖和插件配置提取出来,在简化POM的同时还可以促进各个模块配置的一致性,父模块的打包方式必须为pom。
继承元素:
groupId:项目组ID,项目坐标的核心元素
version:项目版本,项目坐标的核心因素
description:项目的描述信息
organization:项目的组织信息
inceptionYear:项目的创始年份
url:项目的URL地址
developers:项目的开发者信息
contributors:项目的贡献者信息
distributionManagement:项目的部署配置
issueManagement:项目的缺陷跟踪系统信息
ciManagement:项目的持续集成系统信息
scm:项目的版本控制系统
malilingLists:项目的邮件列表信息
properties:自定义的Maven属性
dependencies:项目的依赖配置
dependencyManagement:项目的依赖管理配置
repositories:项目的仓库配置
build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting:包括项目的报告输出目录配置、报告插件配置等
Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement 元素。使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。Maven 会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用在这个dependencyManagement 元素中指定的版本号。
注意:dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖。
当出现依赖冲突时,会先遵循短路优先,再遵循声明优先
路径长度相同的情况下,又可以分为是否有在同一个pom.xml两种情况
a、覆盖
如果在同一pom.xml文件中有2个相同的依赖;后面声明的会覆盖前面的依赖
但这里要说严禁使用本情况,严禁在同一个pom中声明两个不同的依赖
b、优先
如果是在不同pom.xml中有2个相同的依赖;则先声明的依赖,会覆盖后面声明的依赖
消除传递依赖
1、在子pom中将不想依赖的jar移除
<exclusions>
<exclusion>
<groupId>org.lonecloud.A</groupId>
<artifactId>A</artifactId>
</exclusion>
</exclusions>
2、从项目B入手,使项目A依赖项目B时,排除A对项目C的依赖。在项目A中按照正常的方式引入对项目B的依赖即可,这个时候,项目A就不会依赖项目C了。如果项目A用到了项目B中涉及项目C的功能,则需要在项目A的 pom.xml 文件中额外配置对项目C的依赖。
项目B的配置片段如下
<dependency>
<groupId>sample.ProjectC</groupId>
<artifactId>Project-C</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
四、Maven快照版本和发布版本
snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本。
五、pom.xml详解
约束详解:https://blog.csdn.net/lengxiao1993/article/details/77914155
基础配置
<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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- 模型版本。maven2.0必须是这样写,现在是maven2唯一支持的版本 -->
<modelVersion>4.0.0</modelVersion>
<!-- 公司或者组织的唯一标志,并且配置时生成的路径也是由此生成, 如com.winner.trade,maven会将该项目打成的jar包放本地路径:/com/winner/trade -->
<groupId>com.winner.trade</groupId>
<!-- 本项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>trade-core</artifactId>
<!-- 本项目目前所处的版本号 -->
<version>1.0.0-SNAPSHOT</version>
<!-- 打包的机制,如pom,jar, maven-plugin, ejb, war, ear, rar, par,默认为jar -->
<packaging>jar</packaging>
<!-- 帮助定义构件输出的一些附属构件,附属构件与主构件对应,有时候需要加上classifier才能唯一的确定该构件 不能直接定义项目的classifer,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的 -->
<classifier>...</classifier>
<!-- 定义本项目的依赖关系 -->
<dependencies>
<!-- 每个dependency都对应这一个jar包 -->
<dependency>
<!--一般情况下,maven是通过groupId、artifactId、version这三个元素值(俗称坐标)来检索该构件, 然后引入你的工程。如果别人想引用你现在开发的这个项目(前提是已开发完毕并发布到了远程仓库),-->
<!--就需要在他的pom文件中新建一个dependency节点,将本项目的groupId、artifactId、version写入, maven就会把你上传的jar包下载到他的本地 -->
<groupId>com.winner.trade</groupId>
<artifactId>trade-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<!-- maven认为,程序对外部的依赖会随着程序的所处阶段和应用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。 -->
<!--scope包含如下的取值:compile(编译范围)、provided(已提供范围)、runtime(运行时范围)、test(测试范围)、system(系统范围) -->
<scope>test</scope>
<!-- 设置指依赖是否可选,默认为false,即子项目默认都继承:为true,则子项目必需显示的引入,与dependencyManagement里定义的依赖类似 -->
<optional>false</optional>
<!-- 屏蔽依赖关系。 比如项目中使用的libA依赖某个库的1.0版,libB依赖某个库的2.0版,现在想统一使用2.0版,就应该屏蔽掉对1.0版的依赖 -->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 为pom定义一些常量,在pom中的其它地方可以直接引用 使用方式 如下 :${file.encoding} -->
<properties>
<file.encoding>UTF-8</file.encoding>
<java.source.version>1.5</java.source.version>
<java.target.version>1.5</java.target.version>