为了加快速度,在setting.xml中加一段配置,用国内阿里云的镜像仓库可以去下载各种东西。
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
然后测试下,在终端输入:
进入代码保存的相关目录
cd /Users/wangmeng/Documents/space/learn
构建一个maven工程:
mvn archetype:generate -DgroupId=com.wangmeng.maven -DartifactId=maven-first-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
此时maven会在当前目录下 新建一个目录,名称就是-DartifactId指定的名称。这个这个目录,就可以看到maven自动给我们初始化好了一个工程对应的目录结构。
这就是基本的maven工程目录结构,其中src/main/java目录包含了这个项目的java源码,src/test/java目录包含了测试代码,pom.xml文件就是maven的核心配置文件
pom.xml文件是一个项目最核心的maven配置文件,包含了大量的信息,maven真是基于这里的配置信息来对工程进行构建管理工作的。一个最基本的pom.xml文件如maven生成的pom.xml所示。
<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.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhss.maven</groupId>
<artifactId>maven-first-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>maven-first-app</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
我们项目中的pom.xml是如何依赖以及构建的呢?
全局的maven配置,settings.xml maven的约定:各种约定目录,代码/资源/输出/测试
mvn构建命令:
maven的体系结构图:
每个maven项目都有一个坐标 groupId+artifactId+version+packaging+classifier 五个维度的坐标,唯一定义一个依赖包,任何一个项目,都是用这五个维度唯一定位一个发布包。
例如: groupId: com.wangmeng.oa artifactId: oa-organ version: 1.0.0-SNAPSHOT
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<type></type>
<scope></scope>
<optional></optional>
</dependency>
1,依赖范围:
2,传递性依赖
maven的依赖性传递,就是说会自动递归解析所有的依赖,然后负责将依赖下载下来,所有层级的依赖都会成为我们项目的依赖。
比如说我们依赖于A是compile范围,A依赖于B,B是test范围。那么A只有在测试的时候才会使用B。
传递性依赖机制对依赖范围也是有影响的,比如下面的表格,第一列是一级依赖,第一行是二级依赖,传递性依赖会导致多级依赖的依赖范围交叉在一起,会有影响。
3,依赖调解
依赖传递性会导致依赖冲突的问题,例如
比如A->B->C->X(1.0),A->D->X(2.0),A有两个传递性依赖X,不同的版本
此时就会依赖调解,就近原则,离A最近的选用,就是X的2.0版本
如果A->B->X(1.0)和A->D->X(2.0),路径等长呢?那么会选择第一声明原则,哪个依赖在pom.xml里先声明,就用哪个
4,可选依赖
<optional>true</optional>
此时以来传递失效,不会向上传递。
1,依赖冲突 因为maven的依赖具有传递性,所以就应运而生了依赖的冲突 比如我们同时依赖A和B,此时A依赖了C-1.0, B依赖了D,D依赖了C-2.0
按照上面所说取最短路径,所以我们项目依赖C-1.0 如果C-1.0 有方法CClass.sayHello() C-2.0中添加新方法CClass.printHello()
D调用C-2.0中的printHello()这个方法,这时因为项目中依赖的是C-1.0,所以使用时就会报错
2,解决依赖冲突 mvn depedency:tree命令,查看项目中maven依赖关系树,然后将有冲突的依赖找出来,在pom中使用exclusion处理。
A --C-1.0 B --D --C-2.0
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
maven仓库的大类分为本地仓库和远程仓库两种,如果我们声明了一个依赖,那么在构建打包的时候,先会去本地仓库找,这个本地仓库的地址默认就是~/.m2/repository目录下面,当然settings.xml文件是可以修改这个地址的。如果本地仓库找不到,那么就会去远程仓库找,默认是去maven自己的中央仓库里找,maven的中央仓库几乎涵盖所有的依赖,然后会将中央仓库的依赖下载下来放到本地仓库,缓存起来,供下次使用。