文章目录
1. 引言
Maven
工具用了5年了,用的我都没怎么在意它,因为实在是太好用了。最近要迁移一个不是Maven
的老平台,发现自己对Maven
的细节并不算熟悉,就利用一天时间,来学习一下吧,就当做个笔记吧。
2. 重要知识点
2.1 约定的目录结构
约定的目录结构对于 Maven
实现自动化构建而言是必不可少,就拿自动编译来说 Maven
必须能找到 Java
源文件,下一步才能编译,而编译之后也必须有一个准确的位置保持编译得到的字节码文件。
在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式:通过配置的形式明确告诉它或者基于第三方工具或框架的约定。
Maven
对工程目录结构的要求就属于后面的一种。(遵循:约定 > 配置 > 编码)
2.2 何为类路径?
打包特点:
src
目录下所有文件会打包在classes
文件目录下,该classes
目录,会被放在WEB-INF
目录下WebContent
下的所有目录,会被放在项目(Chiken
)目录下classes
的目录是所谓的类路径,所以==src
也被称为类路径==
2.3 构建过程的主要环节
清理:将以前编译得到的旧的class
字节码文件删除,为重新编译做好准备
编译:将 Java
源程序编译为class
字节码文件
测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性
报告:在每一次测试后以标准的格式记录和展示测试结果
打包:将一个包含诸多文件的工程封装为压缩文件用于安装或部署。Java
工程对应 jar
包,Web
工程对应 war
包
安装:在 Maven
环境下特指将打包的结果——jar
包或 war
包安装到本地仓库中
部署:将打包的结果部署到远程仓库或将 war
包部署到服务器上运行
2.4 Maven 中的核心概念
2.4.1 POM
Project Object Model
:项目对象模型。将 Java
工程的相关信息封装为对象作为便于操作和管理的模型。Maven
工程的核心配置。可以说学习 Maven
就是学习 pom.xml
文件中的配置。
2.4.2 Maven 的坐标
GAV
坐标介绍略过,此处说一下如何通过坐标到仓库中查找 jar
包?
<dependency>
<groupId>com.scorpios.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
将 GAV三个向量连起来:com.scorpios.maven+Hello+0.0.1-SNAPSHOT
以连起来的字符串作为目录结构到仓库中查找
com/scorpios/maven/Hello/0.0.1-SNAPSHOT/Hello-0.0.1-SNAPSHOT.jar
注意:我们自己的 Maven
工程必须执行安装操作才会进入仓库。安装的命令是:mvn install
2.4.3 常用的Maven命令
注意:执行与构建过程相关的Maven
命令,必须进入pom.xml
所在的目录。(很重要!!!)
常用命令:
mvn clean
: 清理mvn compile
: 编译主程序mvn test-compile
: 编译测试程序mvn test
: 执行测试mvn package
: 打包mvn install
: 安装mvn site
: 生成站点
修改默认本地仓库的位置可以让Maven
核心程序到我们事先准备好的目录下查找插件:
找到Maven解压目录\conf\settings.xml,在settings.xml文件中找到localRepository标签
将/path/to/local/repo从注解中取出
将标签体内容修改为已经准备好的Maven
仓库目录。
2.4.4 依赖管理
依赖管理是 Maven
中最关键的部分,我们使用 Maven
最主要的就是使用它的依赖管理功能。要理解和掌握 Maven
的依赖管理,我们只需要解决一下几个问题:
2.4.4.1 依赖的目的是什么
当 A jar
包用到了 B jar
包中的某些类时,A
就对 B
产生了依赖,这是概念上的描述。那么如何在项目中以依赖的方式引入一个我们需要的 jar
包呢?
答案非常简单,就是使用 dependency
标签指定被依赖 jar
包的坐标就可以了。
<dependency>
<groupId>com.scorpios.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
2.4.4.2 依赖的范围scope
大家注意到上面的依赖信息中除了目标 jar
包的坐标还有一个 scope
设置,这是依赖的范围。依赖的范围有几个可选值,我们用得到的是:compile
、test
、provided
三个。
下面从项目结构角度理解 compile
和 test
的区别
依赖范围 | 对主程序是否有效 | 对测试程序是否有效 | 是否参与打包 | 是否参与部署 | 典型例子 |
---|---|---|---|---|---|
compile(默认) | 有效 | 有效 | 参与 | 参与 | |
test | 无效 | 有效 | 不参与 | 不参与 | junit |
provided | 有效 | 有效 | 不参与 | 不参与 | servlet-api.jar |
2.4.4.3 依赖的传递性
A 依赖 B,B 依赖 C,A 能否使用 C 呢?
那要看 B 依赖 C 的范围是不是 compile
,如果是则可用,否则不可用。
2.4.4.4 依赖的排除
如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven
会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时
候将 B 排除。
<dependency>
<groupId>com.scorpios.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
<!--排除commons-logging的依赖-->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
2.4.4.5 依赖的原则:解决 jar 包冲突
路径最短者优先,以下图为例:
Hello.jar
中使用log4j.1.2.17.jar
HelloFriend.jar
中使用log4j.1.2.14.jar
那么MakeFriend.jar
在使用HelloFriend.jar
时,用的是1.2.14
的版本
路径相同时先声明者优先,以下图为例:
OurHello.jar
中使用log4j.1.2.17.jar
HelloFriend.jar
中使用log4j.1.2.14.jar
那么MakeFriend.jar
同时在使用HelloFriend.jar
和OurFriends.jar
时,用的是1.2.14
的版本
这里“声明”的先后顺序指的是 dependency
标签配置的先后顺序。
2.4.5 继承
下面以一个例子来说一下继承,有三个工程:Hello.jar
、HelloFriend.jar
、MakeFriends.jar
Hello
依赖的junit:4.0
HelloFriend
依赖的junit:4.0
MakeFriends
依赖的junit :4.9
由于test
范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。现在要求统一管理各个模块工程中对junit
依赖的版本,如何做?
解决思路:将junit
依赖统一提取到“父”工程中,在子工程中声明junit
依赖时不指定版本,以父工程中统一设定的为准。同时也便于修改。
操作步骤:创建一个Maven
工程作为父工程。注意:打包的方式是pom
<groupId>com.scorpios.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaing>
在子工程中声明对父工程的引用
<parent>
<groupId>com.scorpios.maven</groupId>
<artifactId>HelloFriend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!--以当前文件为基准的父工程pom.xml文件的相对路径-->
<relativePath>../Parent/pom.xml</relativePath>
</parent>
将子工程的坐标中与父工程坐标中重复的内容删除,在父工程中统一管理junit
的依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</junit>
<artifactId>junit</artifactId>
<version>4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子工程中删除junit
依赖的版本号部分
注意:配置继承后,执行安装命令时要先安装父工程。