Maven 教程
一、Maven简介
Maven是一个开源的构建工具,它可以帮助我们管理项目的构建过程,管理项目的生命周期,jar包依赖关系等。Maven配合持续集成可以实现自动化的编译、测试、打包、发布等强大的功能,尤其在持续集成上有为我们带来了很大便利。
二、Maven的简单命令及配置
下载Maven https://maven.apache.org
解压并配置环境变量
1、首先解压Maven到任意目录:
2、新建环境变量
M2_HOME
,值为 Maven主目录
3、在
Path
变量中添加 Maven的bin目录
4、测试 Maven 是否安装成功
- 更改Maven 默认仓库地址
默认情况下Mavne 会将jar包插件等下载到 ${user.home}/.m2/repository 下,在Windows 系统下通常是用户目录下的.m2隐藏文件夹,这个文件夹在C盘,我们可以通过更改 Maven的配置文件 M2_HOME/conf/setting.xml 来更改默认的本地仓库位置
- Eclipse中设置maven
在Eclipse中设置使用自己下载的Maven ***Windows->Preferences->Maven->Installations->add ***
然后勾选新添加的 Mavne 并应用设置 在选择
User Setting
设置 配置文件
第一个
Global Setting
为全局设置,一般选择M2_HOME/conf/setting.xml
;User Setting
是用户设置,一般copy 一份setting.xml
到任意位置,然后根据自己需要改变一些内容;Maven的配置文件同样遵循”就近原则”;也就是说User Setting
可以覆盖Global Setting
;如果仅仅自己使用的话,也可以懒一点 两个都选择 M2_HOME/conf/setting.xml,然后只更改 一个配置文件就行了。
三、Maven的使用
- 在Eclipse中建立Maven项目
首先 New 一个
Maven Project
然后直接下一步(让你选择工作空间啥的,默认就行)
选择骨架类型,一般常用的 是
quickstart
和web app
;骨架的意思是项目的目录结构,maven采用约定优于配置的理念,项目结构已经约定好了,有兴趣可以自己打开工作空间看一下。
填写项目坐标(如果为一个模块,写坐标打包后可被其他项目引用);Artifact ID将作为项目名称。
- 简单的 jar 包管理
Maven可以很好的为我们管理jar 包中的依赖关系,而我们不必进行像以前一样去下载 jar包,然后添加
class path
这种繁琐的操作,使用Maven后只要我们得知了该jar的仓库坐标,在POM文件
中添加其坐标后,Maven将自动下载并将其加入class path
中。假设现在我们需要使用SpringMVC
,首先到 maven仓库 搜索其坐标。
然后打开选择一个版本
复制Maven坐标
将其坐标加入到
POM文件
中
稍等片刻,Maven自动下载jar包并加入
classpath
中
- maven的请求下载jar包工作流程如下图所示(有点丑……)
- Maven的常用命令
1 |
|
在 Eclipse 中可右键项目或
POM文件
,选择Run AS
中的Maven build…
选项手动输入多个命令,Maven将依次执行,截图如下
- 项目模块间的引用
在实际开发中,通常我们将项目分为N多模块进行开发,我们可以使用Maven建立多个项目,然后如果项目模块关联时,比如A模块要调用B模块的方法,我们只需在B项目上运行
mvn clean
、mvn install
命令,将其发布到本地仓库,其他模块可根据其坐标直接引入即可。
- Maven中的隐含变量
在项目多模块的配置时,groupid往往是重复的,某些高级设置时某些位置也可能是重复的,Maven为我们提供了通过变量引用的方式来动态拿到指定值.
Maven提供了三个隐式的变量可以用来访问
环境变量
、POM信息
和Maven Settings
:
- env变量:
env变量,暴露了你操作系统或者shell的环境变量。如在Maven POM中一个对${env.PATH}的引用将会被${PATH}环境变量替换,在Windows中为%PATH%.
- project变量
project变量暴露了POM,是使用最多的一个变量,可以使用点标记(.)的路径来引用POM元素的值;如下图
具体值参考如下(eclipse一般都有提示,没有自行引入maven的dtd文件,此段内容引自 iteye):
1 |
|
四、Maven的依赖
每个项目都有其classpath,在Maven管理下的项目实际上有3个classpath(
编译classpath
、测试classpath
、运行classpath
);每个被maven管理的jar包在这三种classpath
是否生效及如何选择称之为maven的依赖管理,Maven依赖管理可通过<dependency>
下的<scope>
标签设置,其值含义如下
1 |
|
例如我们设置JUint,只有测试时用到,scope 只需设置成 test即可
- Maven依赖传递性
当A项目依赖某一jar包,比如log4j 时,将其发布到本地仓库后,B项目进行引用时,则同样会依赖log4j;这种情况称之为
Maven的依赖传递
,当scope
设置为test
时,则依赖不会被传递。
- Maven复杂依赖
单项目依赖多模块,多模块中jar包版本冲突,如下图
在此种情况下,Maven无法自动判断jar包x的版本;模块C中的jar包x版本取决于C模块的pom文件中 模块A、B的书写位置,也就是说谁先写在上面,那么就先使用谁的,如下
单项目依赖多模块,多模块中jar包版本冲突,但单项目(模块C)中jar包x版本却并非取决于书写顺序,情况如下图
假设模块C的pom文件中仍是先写得模块A;但此时在 模块C中 jar包x的版本仍是2.0;原因是模块A依赖了jar包K,而jar包K又依赖了jar包x;相当于jar包x到模块C之间存在二级关系,此时Maven的依赖选择以最近的为主,如果距离(层级)相同,那么再根据书写顺序判定选择那个,否则优先选择距离(层级)最近的,在Eclipse中可通过视图查看依赖层级关系,如下
- Maven依赖的排除
当项目模块中存在jar包冲突时,或想使用某个模块中指定的jar包版本,我们可以使用
标签进行排除某个jar包,如下
五、Maven的聚合与继承
- Maven的聚合
我们已经知道Maven中多模块(项目)是可以互相引用的,但在实际开发中往往会遇到一些问题;当模块足够多时,每一次编译打包也就意味着我们要在N多个模块(项目)上执行 clean 、package 等命令,这显然是不能接受的;Maven为我们提供了项目(模块)的聚合功能,也就是说模块最终要统一到一个项目,每次打包编译,我们只需对 “总项目” 进行即可,而无需关心各个模块
1、首先我们创建一个没有骨架的项目(new 一个Maven项目),在下面这步注意要勾选 “跳过骨架选择”
2、填入相关信息,注意打包形式选择pom
3、创建好项目以后我们编辑pom文件,使用
标签指定该项目聚合哪些项目(模块) 标签使用相对路径,指向其他项目(模块),一般都是 ../xxxx
4、此时对聚合项目执行一下
clean compile
测试一下,控制台打印如下,可以看出,Maven依次对3个项目执行了相关操作
- Maven的集成
当成功聚合了多个模块以后,我们还会发现在每个项目模块中存在大量的相同代码,这让我们感觉很不爽;有点 “造轮子” 的嫌疑,当然Maven同样支持继承的操作,也就是说将模块中的相同代码放到父类项目(模块)中,其他模块只需继承即可使用,同时也能很好地解决jar包版本冲突问题
1、首先看一下 各个模块的pom文件,这里面很多都是重复的
2、我们同样新建一个Maven项目,跳过骨架创建
3、然后我们提取其他子模块pom文件中的共有部分放入父pom文件中(以下为父pom文件),包括共有的定义以及每个项目的依赖jar包(依赖的jar包需要使用
<dependencyManagement>
标签来管理)
4、此时我们可以在子项目模块中通过
标签指定继承的Pom文件
注意:聚合
<module>
标签指定的是相对的项目,而继承指定的则是相对的pom文件
5、当继承后我们便可以删除公有的相同内容,如
等;同时依赖的jar包也可不必指定版本
6、到此,继承完成,由于依赖jar包都来自父pom,同时子pom依赖的jar包无需书写版本,这样在一定程度上保证了jar包版本的统一性;同时我们可以发现,聚合和继承十分相似,其实我们可以将聚合也加入到这个pom中来,实现一个项目对多个项目(模块)的继承与聚合,如下为示例的pom文件。
1 |
|