Maven 是目前最流行的自动化构建工具,对于生产环境下多框架、多模块整合开发有重要作用。Maven 是一款在大型项目开发过程中不可或缺的重要工具。(自己粗略写了一个SSM项目之后,回顾头来看这个,会发现更有感觉)
Maven——Maven介绍——史上最烂系列
Maven——Maven核心概念——史上最烂系列
Maven 能够实现自动化构建是和它的内部原理分不开的,这里我们从 Maven 的九个核心概念入手, 看看 Maven 是如何实现自动化构建的
Maven 的核心程序中仅仅定义了抽象的生命周期,而具体的操作则是由 Maven 的插件来完成的。可是 Maven 的插件并不包含在 Maven 的核心程序中,在首次使用时需要联网下载。
小知识:Maven为什么要配置镜像仓库
mvn compile 编译
mvn clean 清理
mvn test-compile 测试
mvn package 打包
注意:运行Maven命令时一定要进入pom.xml文件所在的目录!
举例:在如下路径下,创建了Hello的Maven工程,运行maven命令,
目录结构如下(写上测试类进行测试)
Hello
|—src
|—|---main
|—|---|—java
|—|---|—resources
|—|---test
|—|---|—java
|—|---|—resources
|—pom.xml
执行mvn compile命令
执行mvn test-compile命令
执行mvn package命令
执行mvn clean命令
约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环,就拿自动编译来说,Maven 必须 能找到 Java 源文件,下一步才能编译,而编译之后也必须有一个准确的位置保持编译得到的字节码文件。
我们在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式:
Project Object Model:项目对象模型。将 Java 工程的相关信息封装为对象作为便于操作和管理的模型。 Maven 工程的核心配置。可以说学习 Maven 就是学习 pom.xml 文件中的配置。(相当于web.xml对于动态web工程)
数学中的坐标
[1]在一个平面中使用 x、y 两个向量可以唯一的确定平面中的一个点。
[2]在空间中使用 x、y、z 三个向量可以唯一的确定空间中的一个点。
Maven坐标
使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。
[1]groupid:公司或组织的域名倒序+当前项目名称
[2]artifactId:当前项目的模块名称
[3]version:当前模块的版本
#大到小
<groupId>com.atguigu.mavengroupId>
<artifactId>HelloartifactId>
<version>0.0.1-SNAPSHOTversion>
[1]将 gav 三个向量连起来
com.atguigu.maven+Hello+0.0.1-SNAPSHOT
[2]以连起来的字符串作为目录结构到仓库中查找
com/atguigu/maven/Hello/0.0.1-SNAPSHOT/Hello-0.0.1-SNAPSHOT.jar
不管是什么样的 jar 包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
Maven 中最关键的部分,我们使用 Maven 最主要的就是使用它的依赖管理功能。要理解和掌握 Maven 的依赖管理,我们只需要解决一下几个问题(以子目录形式出现):
当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,这是概念上的描述。那么如何在项目 中以依赖的方式引入一个我们需要的 jar 包呢? 答案非常简单,就是使用 dependency 标签指定被依赖 jar 包的坐标就可以了。
对我们自己开发的Maven工程(比如上述的Hello工程),使用mvn install命令安装后就会进入仓库
比如这是我创建了一个HelloFriend的Maven工程,pom.xml中依赖了Hello工程
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.atstudying.mavengroupId>
<artifactId>HelloFriendartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>HelloFriendname>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.0version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.atstudying.mavengroupId>
<artifactId>HelloartifactId>
<version>0.0.1-SNAPSHOTversion>
<scope>compilescope>
dependency>
dependencies>
project>
这时在HelloFriend的工程中使用mvn compile命令会报无法找到Hello工程的错误,我们要在Hello工程中使用mvn install命令,把该工程放入到(本地仓库)默认仓库,Maven解析依赖信息时会到本地仓库查找依赖的jar包,这时在调用mvn compile命令就会成功,如下图
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.0version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.atstudying.mavengroupId>
<artifactId>HelloartifactId>
<version>0.0.1-SNAPSHOTversion>
<scope>compilescope>
dependency>
大家注意到上面的依赖信息中除了目标 jar 包的坐标还有一个 scope 设置,这是依赖的范围。依赖的范 围有几个可选值,我们用得到的是:compile、test、provided 三个。
compile | test | provided | |
---|---|---|---|
主程序 | 可以 | 不可以 | 可以 |
测试程序 | 可以 | 可以 | 可以 |
参与部署 | 可以 | 不可以 | 不可以 |
<dependency>
<groupId>com.atguigu.mavengroupId>
<artifactId>HelloartifactId>
<version>0.0.1-SNAPSHOTversion>
<scope>compilescope>
<exclusions>
<exclusion>
<groupId>commons-logginggroupId>
<artifactId>commons-loggingartifactId>
exclusion>
exclusions>
dependency>
对同一个框架的一组 jar 包最好使用相同的版本。为了方便升级框架,可以将 jar 包的版本信息统一提 取出来
步骤如下
统一声明版本号
<!---其中 atstudying.spring.version 部分是自定义标签。 ->
<properties>
<atstudying.spring.version>4.1.1.RELEASEatguigu.spring.version>
properties>
引用前面声明的版本号
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>${atguigu.spring.version}version>
dependency>
……
dependencies>
什么是 Maven 的生命周期?
Maven 生命周期定义了各个构建环节的执行顺序,有 了这个清单,Maven 就可以自动化的执行构建命 令了。
Maven 有三套相互独立的生命周期,分别是:
1:Clean Lifecycle 在进行真正的构建之前进行一些清理工作。
2:Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
3:Site Lifecycle 生成项目报告,站点,发布站点。
它们是相互独立的,你可以仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。当然你也可以 直接运行 mvn clean/install/site 运行所有这三套生命周期。
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比 如,运行 mvn clean,这个 clean 是 Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段。 如下
Clean 生命周期:
Clean 生命周期一共包含了三个阶段:
1:pre-clean 执行一些需要在 clean 之前完成的工作
2:clean 移除所有上一次构建生成的文件
3:post-clean 执行一些需要在 clean 之后立刻完成的工作
Site 生命周期
Site 生命周期一共包含了四个阶段:
1:pre-site 执行一些需要在生成站点文档之前完成的工作
2:site 生成项目的站点文档
3:post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
4:site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大 的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。
Default 生命周期
Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里, 只解释一些比较重要和常用的阶段,如下:
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录。
test-compile 编译测试源代码。
process-test-classes test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package package 接受编译好的代码,打包成可发布的格式,如 JAR。
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
例如我们运行 mvn install 的时候 ,代码会 被编译,测试,打包。这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。此外,Maven 的插 件机制是完全依赖 Maven 的生命周期的,因此理解生命周期至关重要。 (从上面就可以理解了)
Hello |
|
---|---|
HelloFriend |
|
MakeFriend |
|
此时如果项目需要将各个模块的junit版本统一为4.9,那么到各个工程中手动修改无疑是非常不可取的。 使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
步骤如下:
1: 创建父工程,在父工程中管理依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.9version>
<scope>testscope>
dependency>
dependencies>
dependencyManagement>
2:在子工程中引用父工程
<parent>
<groupId>com.atguigu.mavengroupId>
<artifactId>ParentartifactId>
<version>0.0.1-SNAPSHOTversion>
<relativePath>../Parent/pom.xmlrelativePath>
parent>
3:在子项目中重新指定需要的依赖,删除范围和版本号
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
dependencies>
将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进 行 clean 操作。而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
在总的聚合工程中使用 modules/module 标签组合,指定模块工程的相对路径即可
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
dependencies>
我们可以到 maven仓库 搜索需要的 jar 包的依赖信息。