基于项目对象模型(POM)的概念,Maven可以从一个中心资料片管理项目构建,报告和文件。
1.环境搭建
1.1 下载
1.2 添加 M2_HOME
添加 M2_HOME 环境变量到 Windows 环境变量,并将其指向你的 Maven 文件夹。
1.3 添加到环境变量 - PATH
更新 PATH 变量,添加 Maven bin 文件夹到 PATH 的最后,如: %M2_HOME%\bin, 这样就可以在命令中的任何目录下运行 Maven 命令了。
1.4 JAVA_HOME
必须设置JAVA_HOME:D:\Develop\Java\jdk1.8.0_181\jre
1.5 验证
运行命令mvn -v
的时候,竟然报错。
Error: JAVA_HOME not found in your environment.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
最后竟在无意中发现了问题,发现以管理员身份运行cmd的时候,不会报此错。
正确结果:
C:\Windows\system32>mvn -version
Apache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-17 23:22:22+0800)
Maven home: E:\开发工具\maven3-2
Java version: 1.8.0_162, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_162\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
2.what?
2.1.构建过程的几个主要环节
构建:
就是以我们编写的Java代码、框架配置文件、国际化等其他资源文件、JSP页
面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。
- ①清理:删除以前的编译结果,为重新编译做好准备。
- ②编译:将Java源程序编译为字节码文件。
- ③测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
- ④报告:在每一次测试后以标准的格式记录和展示测试结果。
- ⑤打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。
- ⑥安装:在Maven环境下特指将打包的结果——jar包或war包安装到本地仓库中。
- ⑦部署:将打包的结果部署到远程仓库或将war包部署到服务器上运行。
2.2. Maven核心概念
Maven能够实现自动化构建是和它的内部原理分不开的,这里我们从 Maven的九个核心概念入手,看看Maven是如何实现自动化构建的
①POM
②约定的目录结构
③坐标
④依赖管理
⑤仓库管理
⑥生命周期
⑦插件和目标
⑧继承
⑨聚合
3.How?
3.1 常用Maven命令
① 注意:执行与构建过程相关的Maven命令,必须进入pom.xml
所在的目录。
与构建过程相关:编译、测试、打包.............
② 常用命令
[1] mvn clean :清理
[2] mvn compile :编译主程序
[3] mvn test-compile :编译测试程序
[4] mvn test:执行测试
[5] mvn package :打包
[6] mvn install:安装
[7] mvn site :生成站点
3.2 关于联网问题,修改本地库
① Maven的核心程序中仅仅定义了抽象的生命周期,但是具体的工作必须由特定的插件来完成。而插件本身并不包含在Maven的核心程序中。
② 当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查找。
③ 本地仓库的默认位置:[系统中当前用户的家目录].m2\repositoryC:\Users\[登录当前系统的用户名]\.m2\repository
④ Maven核心程序如果在本地仓库中找不到需要的插件,那么它会自动连接外网,到中央仓库下载。
⑤ 如果此时无法连接外网,则构建失败。
⑥ 修改默认本地仓库的位置可以让Maven核心程序到我们事先准备好的目录下查找插件
- 找到 Maven 解压目录\conf\settings.xml
- 找到
<localRepository>
标签,从注释中取出 - 改为自己的目录
<localRepository>E:/repo</localRepository>
3.3 POM
Project Object Model:项目对象模型。将 Java工程的相关信息封装为对象作为便于操作和管理的模型。
Maven工程的核心配置。可以说学习Maven就是学习pom.xml
文件中的配置。
3.4 坐标
3.4.1 几何中的坐标
[1]在一个平面中使用x、y两个向量可以唯一的确定平面中的一个点。
[2]在空间中使用x、y、z三个向量可以唯一的确定空间中的一个点。
3.4.2 Maven的坐标
使用如下三个向量在Maven 的仓库中唯一的确定一个 Maven工程。
[1]groupid:公司或组织的域名倒序+当前项目名称
[2]artifactId:当前项目的模块名称
[3]version:当前模块的版本
<groupId>com.atguigu.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
3.4.3 如何通过坐标到仓库中查找 jar包?
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
<name>classworlds</name>
<version>1.1-alpha-2</version>
(1. 将gav连起来
classworlds+classworlds+1.1-alpha-2
(2. 以连起来的字符串作为目录结构到仓库中查找
//groupId/artifactId/version/artifactId-version.jar
classworlds/classworlds/1.1-alpha-2/classworlds-1.1-alpha-2.jar
3.5 仓库
3.5.1 分类
[1]本地仓库:为当前本机电脑上的所有 Maven工程服务。
[2]远程仓库
(1)私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven工程服务。
(2)中央仓库:架设在 Internet上,为全世界所有 Maven工程服务。
(3)中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
3.5.2 仓库中的文件
[1]Maven的插件
[2]我们自己开发的项目的模块
[3]第三方框架或工具的 jar包
※不管是什么样的jar 包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
3.6 依赖
3.6.1 Maven解析依赖信息时会到本地仓库中查找被依赖的 jar
对于我们自己开发的 Maven工程,使用 mvn install
命令安装后就可以进入仓库
3.6.2 依赖的范围
大家注意到上面的依赖信息中除了目标 jar包的坐标还有一个scope
设置,这是依赖的范围。依赖的范围有几个可选值,我们用得到的是:compile、test、provided 三个。
3.6.3 依赖的传递性
①在Hello中添加对spring-core的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
<scope>compile</scope>
</dependency>
②在HelloFriend中查看spring-core是否被加入了运行时环境
③将Hello中对spring-core的依赖范围修改为test,再到HelloFriend中检查没有
④将Hello中对spring-core的依赖范围修改为provided,再到HelloFriend中检查没有
⑤结论
:非compile范围的依赖不能传递,必须在有需要的工程中单独加入
3.6.4 依赖的排除
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.0.RELEASE</version>
<scope>compile</scope>
<!--排除exclusions-->
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
3.6.5 依赖原则
1.作用:解决模块工程之间jar包冲突
2.情景一:路径最短者优先原则
3.情景二:路径相同,先声明者优先原则
3.6.6 依赖版本统一管理
对同一个框架的一组jar包最好使用相同的版本。为了方便升级框架,可以将jar包的版本信息统一提取出来
1)统一声明版本号
<properties>
<atguigu.spring.version>4.0.1.RELEASE</atguigu.spring.version>
</properties>
2)引用前面声明的版本号
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${atguigu.spring.version}</version>
<scope>compile</scope>
</dependency>
3)其他用法,自定义配置
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
3.7 声明周期
3.7.1 什么是Maven的生命周期?
- Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构建命令了。
- Maven有三套相互独立的生命周期,分别是:
- ①Clean Lifecycle在进行真正的构建之前进行一些清理工作。
- ②Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
- ③Site Lifecycle 生成项目报告,站点,发布站点。
它们是相互独立的,你可以仅仅调用 clean来清理工作目录,仅仅调用 site 来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。
每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行mvn clean,这个clean是 Clean生命周期的一个阶段。有 Clean生命周期,也有 clean阶段。
3.7.2 Clean生命周期
Clean生命周期一共包含了三个阶段:
①pre-clean 执行一些需要在 clean之前完成的工作
②clean 移除所有上一次构建生成的文件
③post-clean 执行一些需要在 clean之后立刻完成的工作
3.7.3 Site 生命周期
①pre-site 执行一些需要在生成站点文档之前完成的工作
②site 生成项目的站点文档
③post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
④site-deploy 将生成的站点文档部署到特定的服务器上
这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。
3.7.4 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将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
3.7.5 生命周期与自动化构建
运行任何一个阶段的时候,它前面的所有阶段都会被运行
,例如我们运行 mvn install 的时候,代码会被编译,测试,打包。这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。此外,Maven 的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要。
3.8 在 Eclipse 和 IDEA 使用Maven
3.9 在 IDEA 执行Maven命令
3.10 继承
例子:
Hello版本:junit:4.0
HelloFriend版本:junit:4.0
MakeFriend版本:junit:4.1.1
由于test
范围的依赖不能传递,所以必然会分散在各个模块工程中,很容易造成版本不一致。
需求:统一管理各个模块工程中对unit依赖的版本
解决思路:将 junit 依赖统一提取到“父”工程中,在“子”工程中声明依赖时,不指定版本
,以父工程版本为准,便于修改。
创建父工程和创建一般的 Java工程操作一致,唯一需要注意的是:打包方式处要设置为 pom。
<groupId>com.atguigu.maven</groupId> <artifactId>Parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging>
在子工程中引用父工程
<parent> <!-- 父工程坐标 --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <relativePath>从当前目录到父项目的 pom.xml 文件的相对路径</relativePath> </parent>
实例
<!--子工程声明引用父工程--> <parent> <groupId>com.atguigu.maven</groupId> <artifactId>Parent</artifactId> <version>1.0-SNAPSHOT</version> <!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径--> <relativePath>../Parent/pom.xml</relativePath> </parent>
将子工程中与父工程重复坐标部分删除
groupId 的定义是多余的, 因为它从父报表继承, 定义<groupId>是不必要的, 因为它已经在父 pom.xml 中定义.
在父工程中统一管理junit依赖
将Parent项目中的dependencies标签,用dependencyManagement标签括起来<!--配置依赖管理--> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> <scope>test</scope> </dependency> </dependencies> </dependencyManagement>
在子项目中重新指定需要的依赖,删除范围和版本号
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <!--子工程删除版本号--> <!--<version>4.11</version>--> <scope>test</scope> </dependency>