1.什么是maven
maven是基于项目对象模型(POM),可以通过一小段描述信息(配置文件)来管理项目的构建、报告和文档的软件项目管理工具。是一个采用纯Java编写的开源项目管理工具,所有的项目配置信息都被定义在一个叫做POM.xml的文件中,通过该文件maven可以管理项目的整个生命周期,包括清除、编译、测试、报告、打包、部署等。
2.maven模型
3.maven作用
maven是跨平台的项目管理工具。主要服务于基于Java平台的项目构建,依赖管理和项目信息管理。jar文件不用在每个项目保存,只需要放在仓库即可。maven可以指定jar的依赖范围。
PS.maven的本地仓库repository就是本地下载的jar存放路径。
4.maven项目规约
maven项目规约,就是maven项目的目录结构。
maven项目的目录结构遵守以下规范:
src/main/java | 存放项目的.java文件(开发源代码) |
src/main/resources | 存放项目配置文件,如果没有配置文件则该目录可无,如spring,hibernate配置文件 |
src/main/webapp | 存放web项目资源文件(web项目才有) |
src/test/java | 存放所有测试.java文件(测试源代码) |
src/test/resources | 测试配置文件,如果没有配置文件该目录可无 |
target | 项目输出位置(可无) |
pom.xml | maven项目核心配置文件 |
也就是说如果是一个maven项目那么它的根目录下必定存在src文件夹和pom.xml。
5.构建maven项目命令的使用
注意:先进入项目目录后再操作
命令 | 说明 |
mvn clean | 清除原来的编译结果 |
mvn compile | 编译 |
mvn test | 运行测试代码,mvn test -Dtest=类名 //单独运行测试类 |
mvn package | 打包项目,mvn package -Dmanven.test.skip=true //打包时不执行测试 |
mvn install | 将项目打包并安装到本地仓库 |
mvn deploy | 发布到本地仓库或者服务器 |
6.maven仓库
maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,就称之为仓库。(仓库就是存放依赖和插件的地方)
maven的仓库有两大类:
- 本地仓库
- 远程仓库,在远程仓库中又分成了3种:中央仓库、私服、其它公共库。
本地仓库:就是maven在本机存储构件的地方。maven的本地仓库,在安装maven后并不会创建,它是在第一次执行maven命令的时候才被创建。
中央仓库:包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。开源的Java项目依赖的构件都可以在这里下载到。
私服:是一种特殊的远程仓库,它是架设在局域网内的仓库。
7.maven坐标
- maven坐标主要组成:
groupId:定义当前maven项目隶属项目、组织
artifactId:定义实际项目中的一个模块
version:定义当前项目的当前版本
packaging:定义该项目的打包方式(pom/jar/war,默认为jar)
groupId、artifactId、version简称为GAV。
- maven为什么要使用坐标:
maven世界拥有大量构件,需要找一个用来唯一标识一个构建的统一规范,拥有了统一规范,就可以把查找工作交给机器。
- 如何获得maven坐标:
maven坐标查询网站:https://mvnrepository.com/
网站上可以搜索具体的组织或项目关键字,之后复制对应的坐标到pom.xml中。
8.maven依赖管理
- 依赖范围
依赖范围scope用来控制依赖和编译、测试,运行的classpath的关系。具体的依赖范围有如下6种:
- compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效
- test:测试依赖范围。只对于测试classpath有效
- provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
- runtime:运行时提供。例如:jdbc驱动
- system:系统范围,自定义构件,指定systemPath;跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它。
- import:只使用在<dependencyManagement>中,表示从其它的pom中导入dependency的配置。
- 传递性依赖
假设C依赖B,B依赖A,那么称C对B是第一直接依赖,B对A是第二直接依赖,C对A是传递依赖。对于传递性依赖,依赖的范围如下表:
- 可选依赖
在依赖节点dependency中的<optional>可以控制当前的依赖是否向下传递;默认值为false,表示向下传递。
示例:A项目依赖于log4j,然后B项目依赖于A项目;那么如果在A中对log4j依赖的optional配置成false时,B项目中自动传递依赖于log4j。否则反之。
(1)项目A配置slf4j的依赖并设置optional为true
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
<!-- 配置为true时不向下传递此依赖,默认为false -->
<optional>true</optional>
</dependency>
(2)配置项目B依赖于项目A,检查项目B的依赖包
<!-- 依赖于A -->
<dependency>
<groupId>com.yiidian</groupId>
<artifactId>A</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
这时发现项目B没有依赖slf4j-log4j12.
- 依赖冲突
如果直接与间接依赖中包含有同一个坐标不同版本的资源依赖,以直接依赖的版本为准(就近原则)
最终A依赖的版本为2.0.
如果直接依赖中包含有同一个坐标不同版本的资源依赖,以配置顺序下方的版本为准。
如果间接依赖中包含有同一个坐标不同版本的资源依赖,以配置顺序上方的版本为准。
- 排除依赖
在pom中的依赖节点中,如果引入的依赖包含了很多其它的传递依赖,而且项目需要的这些依赖的版本和传递依赖的不相符;那么可以在依赖节点中设置排除依赖节点:<exclusions>然后再添加<exclusions>,其里面的内容包括:所包含坐标以及排除依赖包中所包含的依赖关系。(注意:不需要添加版本,直接按照类别排除)
9.maven生命周期
maven生命周期就是为了对所有的构建过程进行抽象和统一;包括项目清理,初始化,编译,打包,测试,部署等几乎所有构建步骤。
maven有三套相互独立的生命周期,分别是:
- Clean Lifecycle 在进行真正的构建之前进行一些清理工作;
- Default Lifecycle 构建的核心部分,编译,测试,打包,部署等;
- Site Lifecycle 生成项目报告,站点,发布站点。
10.maven继承与聚合
继承为了消除重复,可以把pom中很多相同的配置提取出来,如groupId,version等,在使用的时候子工程直接继承父工程的依赖版本号,子工程中不再需要指定具体版本号,方便统一管控项目的依赖版本问题。