Maven 翻译为"专家"、“内行”,是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念(见补充),Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。
Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。
一句话总结就是:Maven是用来管理项目的依赖(Jar包)和构建项目的。
举个栗子:用java操作MySQL数据库时你需要将MySQL的驱动程序拷贝到项目的lib目录下,有了Maven就不用你手动下载驱动并拷贝了,你只需要将该驱动包的坐标(就是名称和版本信息)告诉Maven就行了。
maven可以用来管理依赖,那这些依赖从何而来呢?从仓库来!
maven的仓库类型- 本地仓库:就在你电脑上
- 远程仓库
①maven中央仓库(地址:http://repo2.maven.org/maven2/)
②maven私服(公司局域网内的仓库,需要自己搭建)
③其他公共远程仓库(例如apache提供的远程仓库,地址:http://repo.maven.apache.org/maven2/)
下面时一个Maven寻找依赖的流程:
前面说到只需要将依赖的坐标告诉Maven,它就会自动把依赖添加到项目中,那坐标长啥样呢?
mysql
mysql-connector-java
5.1.35
上面就是MySQL驱动包的坐标,其中groupId就是机构(公司)名称(就是该依赖的父母),artifactId就是依赖的名称,version就是依赖的版本,是不是通过这三个信息就能唯一确定一个依赖了!(这估计就是坐标的来源吧,二维空间中知道横坐标和纵坐标是不是能确定一个唯一的点!)
依赖范围下面是一个junit的坐标,仔细观察和上面的MySQL驱动坐标是不是有点不一样,不错,除了groupId、artifactId、version之外还有一个scope标签。
junit junit 4.12 test
而这个scope标签就是用来声明依赖的作用范围的!
下面时scope的取值以及对应的作用范围:(默认为complie)
- compile:默认范围,编译测试运行都有效
- provided:在编译和测试时有效
- runtime:在测试和运行时有效
- test:只在测试时有效
- system:在编译和测试时有效,与本机系统关联,可移植性差
常用依赖范围有效性总结
在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。
通过上面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。
依赖冲突由于依赖传递现象的存在, spring-webmvc 依赖 spirng-beans-4.2.4,spring-aop 依赖 spring-beans-5.0.2,但是发现 spirng-beans-4.2.4也 加入到了工程中,而我们希望 spring-beans-5.0.2 加入工程。这就造成了依赖冲突。(即导入spring-webmvc时自动导入了 spirng-beans-4.2.4,但是导入spring-aop时又自动导入了spring-beans-5.0.2,导致同一个依赖在项目中出现了不同的版本)
如何解决依赖冲突-
使用maven提供的依赖调解原则
(1) 第一声明者优先原则:即导入的顺序
(2) 路径近者优先原则:即自定定义 -
排除依赖
在dependency标签中加exclusions标签排除需要排除的依赖 -
锁定版本
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中, 这种方法最常用。
版本锁定的使用方式:
**第一步:**在dependencyManagement标签中锁定依赖的版本
org.springframwork spring-webmvc 5.0.2
第二步:在dependencies标签中声明需要导入的maven坐标
此时无需指定version
项目构建org.springframwork spring-webmvc
前面了解了Maven依赖管理的相关知识,现在来看Maven的第二个功能——项目构建。
在没有使用Maven之前,写的JAVA程序一般都是直接点击IDE的Run来运行,但是项目上线的时候总不能让它一直在IDE中运行吧,总得打个包,然后把它部署到Linux服务器上面,而Maven就能帮助你快捷的打包。
所以简单理解项目构建就是帮你打包。(当然不止是打包,后面慢慢了解)
既然Maven能用来构建项目,那总得有一个项目的样子吧,因此现在来看Maven工程的目录结构。
以上便是一个标准的Maven工程的目录结构。
Maven 生命周期定义了各个构建环节的执行顺序,有了这个顺序清单,Maven 就可以自动化的执行构建命令了。(所谓生命周期就是从出生到死亡,它是不可逆的一个顺序)
Maven 有三套相互独立的生命周期,分别是:
- Clean Lifecycle 在进行真正的构建之前进行一些清理工作
- Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等
- Site Lifecycle 生成项目报告,站点,发布站点
其中,Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中(列出一些重要阶段):
- validate:验证工程是否正确,所有需要的资源是否可用。
- compile:编译项目的源代码。
- test:使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
- package:把已编译的代码打包成可发布的格式,比如 jar、war 等。
- integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。
- verify:运行所有检查,验证包是否有效且达到质量标准。
- install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
- deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享
非常重要:后面周期的执行会把它之前的全执行一遍,比如说你执行了install,那么它会执行validate、complied、test、package、verify和install
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
继承步骤:
注意事项:
- 父工程的打包方式为pom(见补充)
- 子工程中要有parent标签来申明父工程
在maven工程的pom.xml文件中可以使用标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如,拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到一个maven工程中(无需继承关系), 需要打包的时候,只需要在此工程中执行一次打包命令, 其下被聚合的工程就都会被打包了。
上面提到了打包方式,Maven项目的打包类型有三种:pom、jar、war
maven的默认打包方式为jar,当项目为Web项目时就要申明为war,具体做法是在pom.xml文件中声明:
其他war
POM:Project Object Model:项目对象模型。将 Java 工程的相关信息封装为对象作为便于操作和管理的模型。
创作不易,给个一键三连吧



