“ 加紧学习,抓住中心,宁精勿杂,宁专勿多。—— 周恩来”

1、前言
为什么需要学习 Maven 呢?很多同学刚接触 Maven 的时候都会觉得有点迷惑,因为没有 Maven 我们也很好的进行项目的开发。Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理,目前绝大部分企业还是在用 Maven 来构建项目。
那么,使用 Maven 构建项目的好处到底是什么呢?
①添加第三方 jar。比如:我们要集成 Spring 框架,那么传统模式的话需要将 Spring 的相关 jar 导入到 WEB-INF/lib 下面。每个项目都独立使用一份 jar,造成 jar 的重复导入和浪费磁盘空间。而使用 Maven 之后,它本地仓库保存一份 jar,每个工程通过坐标的方式进行引用即可。
②解决 jar 之间的依赖关系。很多时候,jar 之间是互相有依赖的,如果手工导入 jar 的话,我们需要清楚它依赖哪些 jar,并且手工导入依赖 jar,工作量非常的大。然而 Maven 可以很好的帮助我们解决这些头疼的问题。
③工程管理,将工程拆分成多个工程模块,也是微服务模式下最常见的方法。
④提供自动化的编译、测试、打包、部署一条龙服务,没有 Maven 之前,一般是基于 Ant 进行编译项目,Ant 的话需要自定义脚本,Maven 要比 Ant 更加的完善和好用。
构建过程的几个主要环节
清理:删除以前的编译结果,为重新编译做好准备。
编译:将 Java 源程序编译为字节码文件(class)。
测试:运行
src/test/java
包下的测试类。报告:在每一次测试后以标准的格式,记录和展示测试结果。
打包:将项目打包成 jar 或者 war,打包结果放到在 target 下。
安装:将项目的打包结果安装到本地仓库。
部署:将打包的结果部署到远程仓库。
Mave 有它约定的目录结构,具体如下图所示:

2、Maven 的学习
2.1、安装及配置
1)本地安装 Maven
第一步:将 apache-maven-3.3.9-bin.zip 解压
第二步:配置环境变量,类似 JDK 一样配置
第三步:
mvn -v
查看是否安装成功
2)Maven 的基本信息配置
第一步:修改 jdk 版本
#位置:apache-maven-3.3.9\bin\mvn.cmd
set JAVA_HOME=C:/Program Files/Java/jdk1.8.0_171
第二步:修改本地仓库路径,.m2\repository(表示当前用户的家目录,例如:C:\Users [你当前登录系统的用户名])
<!--位置:apache-maven-3.3.9\conf\settings.xml-->
<localRepository>E:/myreposiory</localRepository>
第三步:配置阿里云,如果不指定阿里云,则默认从 Maven 中央仓库下载(国外),速度很慢
<!--位置:apache-maven-3.3.9\conf\settings.xml-->
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>
3)IDE 安装 Maven 插件
现在的 IDEA、Eclipse 基本上都安装有 Maven 插件了,但是旧版本的 Eclipse 是默认没有 Maven 插件,需要手工安装
4)Eclipse 配置 Maven
Window->Preferences 打开弹出框,具体如下所示:

5)创建项目
右击 ->New->Other 打开弹出框,具体如下所示:
下一步进入信息添加,点击完成即可(可以参考第二部分,微服务的规划与构建章节)
2.2、Maven 的坐标
1)什么是坐标
打开项目的 pom.xml 坐标,发现以下信息
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.micro</groupId>
<artifactId>micro-disk</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
groupid:公司或组织的域名倒序 + 当前项目名称
artifactId:当前项目的模块名称
version:当前模块的版本
packaging:表示项目类型(pom,jar,war)
2)依赖
如果 A 项目需要用到 B 项目的功能,传统做法是把 B 项目打成 jar 放到 lib 目录下。但是在 Maven 中则很简单,
第一步:B 项目执行命令 mvn install
把 jar 安装到本地仓库
第二步:在 A 项目的 pom.xml 导入 B 项目的坐标即可
如下所示:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.0</version>
</dependency>
根据坐标信息去本地仓库找到 jar 的位置,具体如下:

3)依赖的范围
注意的是:坐标也是有范围的,常见的范围是 compile、test、provided、runtime、system
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.0</version>
<scope>compile</scope>
</dependency>
compile:缺省值,适用于所有阶段,会随着项目一起发布
test:范围依赖,在一般的编译和运行时都不需要
provided:打包的时候可以不用包进去。比如 servlet.jar 在开发阶段用到,但是部署的时候,由于 Tomcat\lib 有 servlet.jar 了,打包的时候可以去掉它
runtime:无需参与项目的编译,不过后期的测试和运行周期需要其参与。与 compile 相比,跳过编译而已
system:和 provide 相同,不过被依赖项不会从 maven 仓库抓,而是从本地系统文件拿,一定要配合 systemPath 使用
| compile | test | provided | |
|---|---|---|---|
| 主程序 | yes | no | yes |
| 测试程序 | yes | yes | yes |
| 参与部署 | yes | no | no |
4)依赖的传递性
A 依赖 B,B 依赖 C,A 能否使用 C 呢?那要看 B 依赖 C 的范围是不是 compile,如果是则可用,否则,不可用。
依赖的传递原则
第一:C 项目依赖 B 项目;B 依赖 A 项目,则 C 项目的 Dubbo 以 B 项目的 Dubbo 版本为主。

第二:C 项目同时依赖 A 项目和 B 项目,则 C 项目的 Dubbo 版本要看配置顺序(在 pom.xml 里面配置的 dependency 的从上到下的顺序)而定

5)统一管理所依赖 jar 包的版本
把坐标的版本号抽取出来管理
<properties>
<spring.version>4.1.1.RELEASE</spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
2.3、Maven 的生命周期
什么是 Maven 的生命周期?
Maven 生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven 就可以自动化的执行构建命令了。
Maven 的生命步骤有哪些呢?
第一)Clean Lifecycle 在进行真正的构建之前进行一些清理工作
第二)Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署
第三)Site Lifecycle 生成项目报告,站点,发布站点
它们是相互独立的,你可以仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期
常见的命令
mvn clean 表示清理
mvn compile 表示编译主程序
mvn test 表示执行测试
mvn package 表示打包,打包之后再 target 目录下会生成打包文件
mvn install:将包安装至本地仓库
mvn deploy:将最终的包复制到远程的仓库
运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行 mvn install 的时候,代码会 被编译,测试,打包
2.4、继承与聚合
为什么要使用继承?
其实继承跟我们的面向对象思想是一模一样的,当很多工程都依赖相同的坐标使用,可以把这些坐标抽取到父工程,子工程自动继承父工程的所有坐标。
如何配置继承?

温馨提示:也可以用 dependencyManagement 标签把 dependencies 标签括起来,那么子项目不会自动继承父项目的 jar,需要在子项目手工引入,但是不需要写版本号。
聚合工程的创建
①创建父工程(pom)
②在父工程下创建
Module
工程,注意不是Project
工程;③父工程就可以统一管理这些子工程了,可以针对父工程进行统一打包
打开父工程的 pom.xml 发现会有 modules 标签,表示它有哪些子项目
<modules>
<module>disk-service</module>
<module>disk-component</module>
<module>disk-web</module>
<module>disk-user</module>
</modules>
思考:聚合工程的好处是什么呢?
坐标继承,可以把公共的坐标抽取到父工程,子工程就没有必要再重复引入,直接从父工程继承
统一打包,统一的清理、编译、打包等工程。比如:工程之间有依赖,上线的时候,需要理清项目之间的依赖顺序,根据依赖顺序进行先后的打包工作(一个一个的打包);而使用聚合工程之后,直接对父工程进行打包,则会自动对子过程进行打包,不需要再管依赖关系了。
2.5、内置变量
Maven 常见的内置变量说明,可以在 pom.xml 下进行使用
${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为 target
${project.build.outputDirectory} 构建过程输出目录,缺省为 target/classes
${project.build.finalName} 产出物名称,缺省 ${project.artifactId}- ${project.version}
${project.packaging} 打包类型,缺省为 jar
${project.xxx} 当前 pom 文件的任意节点的内容
3、小结
本节内容就先讲到这里,如果大家想深入学习,可以研究私服的搭建、Maven 的常用插件(编译插件、资源插件、Tomcat 插件、Docker 插件的集成等等)。这里主要讲解 Maven 常见的知识点,基本上掌握这些知识,Maven 的基本使用就没啥问题了,主要目的是让没有学习过 Maven 或者 Maven 薄弱的同学(很多同学用过 Maven 只是基本的导入坐标而已,压根不懂如何使用 Maven 来创建微服务项目)补一下基础知识,只有掌握了 Maven,才能更好的理解微服务的架构是怎么创建的。
纸上得来终觉浅,绝知此事要coding...




