Maven使用教程一:Maven基础
使用Maven快速创建一个工程
为了加快速度,在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的约定
这就是基本的maven工程目录结构,其中src/main/java目录包含了这个项目的java源码,src/test/java目录包含了测试代码,pom.xml文件就是maven的核心配置文件
pom.xml初步介绍
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中的顶层元素
- :POM本身的版本号,一般很少改变
- :创建这个项目的公司或者组织,一般用公司网站后缀,比如com.company
- :这个项目的唯一标识,一般生成的jar包名称,会是-.这个格式,比如说myapp-1.0.jar
- :要用的打包类型,比如jar,war等等
- :这个项目的版本号
- :这个项目用于展示的名称,一般在生成文档的时候使用
- :这是这个项目的文档能下载的站点url,一般用于生成文档
- :用于项目的描述
maven体系结构
我们项目中的pom.xml是如何依赖以及构建的呢?
全局的maven配置,settings.xml
maven的约定:各种约定目录,代码/资源/输出/测试
mvn构建命令:
- maven一定会去考虑settings.xml配置文件里的一些配置
- maven会去解析你的maven工程的pom.xml
- maven会去看你的pom.xml里声明了哪些依赖
- maven会去本地仓库里找有没有这些依赖,比如有没有junit
- 如果本地仓库没有junit,那么就会去远程仓库去找,下载junit,所谓的运程仓库里包含了几乎所有的依赖包
- 远程仓库下载到了junit以后,就会放到本地仓库,缓存起来,供你以后去使用,maven的远程中央仓库:https://repo.maven.apache.org/maven2/
maven的体系结构图:
Maven坐标
每个maven项目都有一个坐标
groupId+artifactId+version+packaging+classifier 五个维度的坐标,唯一定义一个依赖包,任何一个项目,都是用这五个维度唯一定位一个发布包。
- groupId:一般是公司或者组织的官网域名倒序来开头,比如com.baidu大头
- artifactId:项目中的某个模块,或者某个服务名
- version:工程的版本号
- packaging:这个工程的发布包打包方式,一般常用的就是jar和war年终
- classifier:很少用,定义某个工程的附属项目,比如hello-world工程的 hello-world-source工程,就是源码
例如:
groupId: com.wangmeng.oa
artifactId: oa-organ
version: 1.0.0-SNAPSHOT
- version中第三位是小版本,一般修复了一些bug 或者轻微的改动会累加第三位小版本
- 第二位是小版本,一般如果一路一些新的功能或模块,或者做了一些重构,会累加第二位小版本
- 第一位是大版本,一般就是如果整体架构有特别的升级或者变化,才会累加第一位大版本。
- SNAPSHOT,就是当前这个版本下的快照版本,代表代码正在开发或者测试中,可以试用,但是没有经过完善测试,不会承诺非常稳定
Maven依赖管理机制
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<type></type>
<scope></scope>
<optional></optional>
</dependency>
1,依赖范围:
- compile:默认,对编译、测试和运行的classpath都有效
- test:仅仅对于运行的测试代码的classpath有效
- provided:编辑和测试的时候有效,但是在运行的时候无效
- runtime:测试和运行classpath有效,但是编译代码时无效
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>
此时以来传递失效,不会向上传递。
Maven依赖冲突
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 dependency: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的多层仓库架构
maven仓库的大类分为本地仓库和远程仓库两种,如果我们声明了一个依赖,那么在构建打包的时候,先会去本地仓库找,这个本地仓库的地址默认就是~/.m2/repository目录下面,当然settings.xml文件是可以修改这个地址的。如果本地仓库找不到,那么就会去远程仓库找,默认是去maven自己的中央仓库里找,maven的中央仓库几乎涵盖所有的依赖,然后会将中央仓库的依赖下载下来放到本地仓库,缓存起来,供下次使用。
感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫
Maven使用教程一:Maven基础的更多相关文章
- WPF教程一:基础
一.WPF简介WPF:WPF即Windows Presentation Foundation,翻译为中文“Windows呈现基础”,是微软推出的基于Windows Vista的用户界面框架,属于.NE ...
- PdgCntEditor系列教程一:基础知识
一.PdgCntEditor是什么? 二.为什么要用PdgCntEditor? 三.怎么用PdgCntEditor? 一.PdgCntEditor是什么? 这是一个目录编辑器,可以创建.编辑PDF.D ...
- eclipse基础环境配置和svn、maven的配置以及maven的安装
安装eclipse和基础配置 第一步:解压eclipse安装包,直接解压就可以,绿色版安装 第二步:启动eclipse,注意这里的eclipse需要依赖jdk,并且版本需要匹配,否则启动会出 现问题. ...
- Maven开发基础总结(Maven自启动,Maven打war包,Maven热部署)
学习内容: 1.不依赖外部Tomcat,自己启动方式部署 2.Maven打war包,远程部署到centOS 3.Maven热部署(不关闭Tomcat部署应用) 做maven开发前提: 1.编码UT ...
- Maven安装、配置及基础
简介: Maven是Apache公司的开源项目,是项目构建工具,用来管理依赖. Maven的优点: 同样的代码实现相同的功能,Maven项目没有Jar包,项目大小更小. maven的优点如何实现: 没 ...
- maven系列之二maven项目的创建和maven项目的结构
maven系列之一简单介绍了maven的基本信息,安装和配置,大家对maven有一个大概的了解,但是在maven项目开发中远远不够,为了进一步了解maven,现在我们介绍maven项目的创建和mave ...
- NGUI系列教程一
NGUI是Unity的一个插件,使用它来制作你的游戏UI必定将事半功倍.为什么这么说呢?首先我们说说GUI与NGUI的区别,GUI是Unity自带的绘制界面工具,它的成像原理是基于表层的,所以执行效率 ...
- maven仓库总结,maven私服搭建
配置pom.xml依赖包时在这里找包的描述: http://search.maven.org/#browse 以java为根目录. mvn archtype:generate -DgroupId=zt ...
- maven仓库总结,maven私服搭建,批量mvn eclipse:eclipse
配置pom.xml依赖包时在这里找包的描述: http://search.maven.org/#browse 以java为根目录. mvn archtype:generate -DgroupId=zt ...
随机推荐
- 【集训Day3 离散化】矩形覆盖
矩形覆盖(planting) [问题描述] 给定在一个平面坐标系上的N(1 <= N <= 100)个矩形区域,这N个矩形可能有相互覆盖的部分.求平面上被所有矩形覆盖的总面积,重复部分只算 ...
- linux目录相关操作
mkdir:新建目录 mkdir [-mp] 目录名称 -m:配置文件权限,直接设置,不需要看默认权限(umask) -p:递归创建目录 rmdir:删除空目录 rmdir [-p] 目录名称 -p: ...
- promise实现图片按照指定的加载顺序执行
promise实现图片按照指定的加载顺序执行,先加载第二张,再加载第一张,最后加载第三张 <!DOCTYPE html> <html lang="en"> ...
- 附011.Kubernetes-DNS及搭建
一 Kubernetes DNS介绍 1.1 Kubernetes DNS发展 作为服务发现机制的基本功能,在集群内需要能够通过服务名对服务进行访问,因此需要一个集群范围内的DNS服务来完成从服务名到 ...
- Linux的awk命令详解
awkawk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,默认以空格为分隔符将每行切片,切开的部分再 ...
- 正则grep 使用介绍
第6周第3次课(4月25日) 课程内容: 9.1 正则介绍_grep上9.2 grep中9.3 grep下扩展把一个目录下,过滤所有*.php文档中含有eval的行grep -r --include= ...
- 能不能自己写个类,也叫java.lang.String?
可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String.由于在tomcat的web应用程序中,都是由webapp自 ...
- Day01-变量/常量/数据类型/流程控制之 if
1.变量 把程序运行的中间结果临时的存在内存里,以便后续的代码调用.代指一些复杂的.过长的数据. 声明变量 name = 'Dylan' # 把数据'Dylan'声明(赋值)给变量 nmae,以便后 ...
- PHP随机生成中国人姓名的类
PHP随机生成类 <?php /*rndChinaName.class.php*/ Class rndChinaName { private $arrXing,$numbXing; privat ...
- JS获得天数差异
//获得天数差异 function datedifference(sDate1, sDate2) { //sDate1和sDate2是2006-12-18格式 var dateSpan, tempDa ...