什么是Maven:Maven是一个项目管理工具,它包含了一个项目对象模型-POM(project object model)、一组标准的集合、一个项目生命周期、一个依赖项目管理系统(Dependency Management System)和用来运行定义在生命周期内的插件(plugin)目标的逻辑。它能够帮助你构建工程、管理Jar包(对于较大的项目工程所依赖的jar包可能成千上百个,这试对jar包的管理就很有必要了)、编译代码、自动运行单元测试,打包,生成报表,甚至能帮你部署项目,生成Web站点。
Maven的生命周期:项目的开发其实就是不断地编译、测试、打包、部署等过程,maven的生命周期就是对所有构建过程的抽象与统一,生命周期包含项目的清理(clean)、初始化、编译、测试(test)、打包、集成测试、验证、部署(install)、站点生成等几乎所有的过程。
Maven有三个相互独立的生命周期:这三个独立的生命周期分别如下:
• CleanLifecycle 在进行真正的构建之前进行一些清理工作。
• DefaultLifecycle 构建的核心部分,编译,测试,打包,部署等等。
• SiteLifecycle 生成项目报告,站点,发布站点。
何为独立:可以仅仅调用clean来清理工作目录,仅仅调用site来生成站点。当然也可以直接运行 “mvn clean install site” 运行所有这三套生命周期。
Maven插件:Maven实质是一个插件的框架,它本身核心并不执行任何的构建任务,所有的这些任务都是交给内置的插件来完成的。像编译是通过maven-compile-plugin实现的、测试是通过maven-surefire-plugin实现的。Maven的每一个任务都对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如maven-compiler-plugin的compile目标用来编译位于src/main/java/目录下的主源码,testCompile目标用来编译位于src/test/java/目录下的测试源码。
Maven提供以下两种类型的插件:
- 构建插件
在生成过程中执行,并应在pom.xml中的
- 报告插件
在网站生成期间执行的,应该在pom.xml中的
除了这些核心插件之外,还有很多优秀的第三方插件:例如,项目中使用了Mybatis,就有一款神奇的maven插件,运行一个命令,就可以根据数据库的表,自动生成Mybatis的mapper配置文件以及DAO层接口模板。
Maven命令:Maven为我们提供了十分丰富的命令,了解maven的命令行操作并熟练运用常见的maven命令还是十分必要的。无论多先进多炫的图形化界面,底层都得靠maven命令来驱动。知其然,知其所以然,方能百战不殆。
(1)maven的命令格式如下:mvn [plugin-name]:[goal-name]
该命令的意思是:执行“plugin-name”插件的“goal-name”目标(或者称为动作)。
(2)用户可以通过两种方式调用Maven插件目标
- 第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已,例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定,因此命令mvn compile实际上是先定位到compile这一生命周期阶段,然后再根据绑定关系调用maven-compiler-plugin的compile目标
- 第二种方式是直接在命令行指定要执行的插件目标,例如mvnarchetype:generate 就表示调用maven-archetype-plugin的generate目标,这种带冒号的调用方式与生命周期无关。
(3)常用的Maven命令:
mvn –version:显示版本信息
mvn clean:清理项目生产的临时文件,一般是模块下的target目录
mvn package:项目打包工具,会在模块下的target目录生成jar或war等文件
mvn install:将打包的jar/war文件复制到你的本地仓库中,供其他模块使用
mvn site:生成项目相关信息的网站
mvn deploy:将打包的文件发布到远程参考,提供其他人员进行下载依赖
mvn eclipse:eclipse:将项目转化为Eclipse项目
mvn tomcat:run:在tomcat容器中运行web应用
mvn dependency:tree:打印出项目的整个依赖树
注意:运行maven命令的时候,首先需要定位到maven项目的目录,也就是项目的pom.xml文件所在的目录。否则,必以通过参数来指定项目的目录。
(4)Maven命令参数:
-D 传入属性参数:例如:mvn package -Dmaven.test.skip=true,以“-D”开头,将“maven.test.skip”的值设为“true”,就是告诉maven打包的时候跳过单元测试
-P 使用指定的Profile配置:例如:mvn package -P dev,其中“dev“为环境(开发、测试、or发布环境)的变量id,代表使用Id为“dev”的profile。
-e 显示maven运行出错的信息
-o 离线执行命令,即不去远程仓库更新包
Maven仓库:
本地仓库:Maven一个很突出的功能就是jar包管理,一旦工程需要依赖哪些jar包,只需要在Maven的pom.xml配置一下,该jar包就会自动引入工程目录。集中存储这些jar包(还有插件等)的地方被称之为仓库(Repository)。不管这些jar包从哪里来的,必须存储在自己的电脑里之后,你的工程才能引用它们。类似于电脑里有个客栈,专门款待这些远道而来的客人,这个客栈就叫做本地仓库。比如,工程中需要依赖spring-core这个jar包,在pom.xml中声明之后,maven会首先在本地仓库中找,如果找到了很好办,自动引入工程的依赖lib库即可。可是,万一找不到呢?那就得上远程仓库去下载到本地了。
远程仓库(中央仓库 or 远程的公共仓库:镜像仓库):中央仓库是默认的远程仓库,此仓库是由Maven社区管理的。实际开发中,一般不会使用maven默认的中央仓库,现在业界使用最广泛的仓库地址为: http://mvnrepository.com/,比默认的中央仓库更快、更全、更稳定,谁用谁知道。
通常情况下,公司都会通过自己的私有服务器在局域网内架设一个仓库代理。私服可以看作一种特殊的远程仓库,代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,先从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务
Maven私服优势:
(1)可以把公司的私有jar包,以及无法从外部仓库下载到的构件上传到私服上,供公司内部使用;
(2)节省自己的外网带宽:减少重复请求造成的外网带宽消耗;
(3)加速Maven构建:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低;
(4)提高稳定性,增强控制:Internet不稳定的时候,maven构建也会变的不稳定,一些私服软件还提供了其他的功能
注:当前主流的maven私服有Apache的Archiva、JFrog的Artifactory以及Sonatype的Nexus。私服也属于远程仓库的范畴。
如果maven没有在本地仓库找到想要的东西,就会自动去配置文件中指定的远程仓库寻找,找到后将它下载到你的本地仓库。如果连远程仓库都找不到想要的东西,maven很生气,累老子跑了一圈都没找到,肯定是你配置写错了,报错给你看。
仓库的配置:仓库的配置是通过setting.xml配置文件来实现的。setting.xml的第一个节点
远程仓库有releases和snapshots两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,有时候会只为开发目的开启对快照版本下载的支持,就需要把
设置发布的权限:私服的作用除了可以给全公司的人提供maven构件的下载,还有一个非常重要的功能,就是开发者之间的资源共享。一个大的项目往往是分模块进行开发的,各个模块之间存在依赖关系,比如一个交易系统,分为下单模块、支付模块、购物车模块等。现在开发下单模块的同学需要调用支付模块中的接口来完成支付功能,就需要将支付模块的某些jar包引入本地工程,才能调用它的接口;同时,开发购物车模块的同学需要调用下单模块的接口,来完成下单功能,他就需要依赖下单模块的某些jar包。这三个模块都在持续开发中,不可能将各自的源码传来传去支持对方的依赖。
解决的方式是这样,每个模块完成了某个阶段性的功能,都会将提供对外服务的接口打成jar包,传到公司的私服当中,谁要使用该模块的功能,只需要在pom.xml文件中声明一下,maven就会像下载其他jar包那样把它引入你的工程。
在开发过程中,在pom中声明的构件版本一般是快照版.
各个模块会不断的上传新的jar包,如果本地项目依赖的是快照版,那么maven一旦发现该jar包有新的发布,就会将它下载下来替代以前的旧版本。比如,支付模块在测试的时候发现有个bug,修复了一下,然后将快照版发布到私服。而你只需要专注于下单模块的开发,所依赖的支付模块的更新由maven处理,不需要关心。一旦你开发的模块修复了一个bug,或者添加了一个新功能等修改,只需要将发布一次快照版本到私服即可,谁需要依赖你的接口谁自然会去私服下载,你也不用关心。
这时就需要使用setting.xml中的servers元素了。需要注意的是,配置私服的信息是在pom文件中,但是认证信息则是在setting.xml中,这是因为pom文件往往是被提交到代码仓库中供所有成员访问的,而setting.xml是存放在本地的,这样是安全的。
注:maven clean deploy和maven clean install的区别:deploy是将该构件部署在私服中,而install是将构件存入自己的本地仓库中
疑问:所有的仓库设置不是已经在setting.xml中配置好了吗,为什么在pom的发布管理节点当中还要配置一个url?答:Setting.xml中配置的是你从哪里下载构件,而POM里配置的是你要将构件发布到哪里。有时候可能下载用的仓库与上传用的仓库是两个地址,但是绝大多数情况下,两者都是由私服充当,就是说两者是同一个地址。
setting.xml配置详解:
maven的配置文件settings.xml存在于两个地方:
1.安装的地方:${M2_HOME}/conf/settings.xml
2.用户的目录:${user.home}/.m2/settings.xml
前者又被叫做全局配置,对操作系统的所有使用者生效;后者被称为用户配置,只对当前操作系统的使用者生效。如果两者都存在,它们的内容将被合并,并且用户范围的settings.xml会覆盖全局的settings.xml。
如果需要创建用户范围的settings.xml,可以将安装路径下的settings复制到目录${user.home}/.m2/。Maven默认的settings.xml是一个包含了注释和例子的模板,可以快速的修改它来达到你的要求。
需要掌握的配置:
实际应用中,经常使用的是
profile可以让maven能够自动适应外部的环境变化,比如同一个项目,在linux下编译linux的版本,在win下编译win的版本等。一个项目可以设置多个profile,也可以在同一时间设置多个profile被激活(active)的。自动激活的 profile的条件可以是各种各样的设定条件,组合放置在activation节点中,也可以通过命令行直接指定。如果认为profile设置比较复杂,可以将所有的profiles内容移动到专门的 profiles.xml 文件中,不过记得和pom.xml放在一起。
activation节点是设置该profile在什么条件下会被激活,常见的条件有如下几个:
(1)os:判断操作系统相关的参数,它包含多个可以自由组合的子节点元素。
(2)jdk:检查jdk版本,可以用区间表示。
(3)property:检查属性值,本节点可以包含name和value两个子节点。
(4)file:检查文件相关内容,包含两个子节点:exists和missing,用于分别检查文件存在和不存在两种情况。
如果settings中的profile被激活,那么它的值将覆盖POM或者profiles.xml中的任何相等ID的profiles。如果想要某个profile默认处于激活状态,可以在