1. 项目构件和依赖管理
Apache Maven 是一种创新的软件项目管理工具,提供了一个项目对象模型(POM)文件的新概念来管理项目的构建,相关性和文档。最强大的功能就是能够自动下载项目依赖库。
pom.xml是Maven的核心配置文件,pom称为Project Object Model(项目对象模型),它用于描述整个Maven项目,所以也称为Maven描述文件。
- 约定(惯例)优先原则
- 标准的目录结构
- 项目描述符,pom.xml
- 三方依赖管理
- 提供了一致的项目构建管理方式
- 插件式的架构,大量的可重用插件
- 很方便地集成IDE
- 开源项目使用Maven
2. 仓库
在Maven的术语中,仓库是这样一个地方或者说是目录,其中存储有项目jar包、库、插件或者任何其他项目指定组件,并且易于被Maven使用。
Maven仓库有三种类型:
- 本地仓库(local):Maven本地仓库是你电脑上的某个目录地址, 它会在你第一次运行maven任意命令时创建。
- 远程仓库(remote):开发者自己定制的包含库或者其他项目jar包的仓库
- 中央仓库(central):Maven中央仓库是由Maven社区提供的仓库,包含大量的常用库。
- 私服:为了节省带宽和时间,在局域网架设私有的仓库服务器,用其代理所有外部的远程仓库,内部的项目还能部署到私服上供其他项目使用。
- 其他公共库
Maven的依赖库查询顺序更改为:
- 在 Maven 本地资源库中搜索,如果没有找到,进入第 2 步,否则退出。
- 在 Maven 中央存储库搜索,如果没有找到,进入第 3 步,否则退出。
- 在 java . net Maven的远程存储库搜索,如果没有找到,提示错误信息,否则退出。
3. pom.xml
Maven 工程结构和内容被定义在一个 xml 文件中,即pom.xml,是 Project Object Model (POM) 的简称,此文件是整个 Maven 系统的基础组件。
<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.0</modelVersion>
<groupId>com.xrq.withmaven</groupId>
<artifactId>withmaven</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
-
modelVersion
指定了当前Maven模型的版本号,对于Maven2和Maven3来说,它只能是4.0.0。 -
groupId
顾名思义,这个应该是公司名或是组织名。一般来说groupId是由三个部分组成,每个部分之间以"."分隔,第一部分是项目用途,比如用于商业的就是"com",用于非营利性组织的就是"org";第二部分是公司名,比如"alibaba";第三部分是你的项目名。 -
artifactId
可以认为是Maven构建的项目名,比如你的项目中有子项目,就可以使用"项目名-子项目名"的命名方式。 -
version
版本号,SNAPSHOT意为快照,说明该项目还在开发中,是不稳定的版本。groupId、artifactId、version三个元素生成了一个Maven项目的基本坐标。 -
scope
依赖范围,用来控制依赖和编译,测试,运行的classpath的关系. 主要的是三种依赖关系如下:- compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效
- test:测试依赖范围。只对于测试classpath有效
- provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为由容器已经提供,例如servlet-api
- runtime:运行时提供。例如:jdbc驱动
在上面的这些元素之外,还有一些元素,同样罗列一下:
-
packing
项目打包的类型,可以使jar、war、rar、ear、pom,默认是jar -
dependencies和dependency
前者包含后者。前面说了,Maven的一个重要作用就是统一管理jar包,为了一个项目可以build或运行,项目中不可避免的,会依赖很多其他的jar包,在Maven中,这些依赖就被称为dependency。
继承或覆盖
可继承项
- 坐标属性
- 依赖配置
- 插件配置
- 一般性信息,如开发者信息
依赖传递、依赖排除
Super POM
- 所有的Maven项目的POM都继承Super POM
- 是Maven的组成部分
- 超级POM定义了一组被所有项目共享的默认配置
依赖传递
A项目依赖B,B项目依赖C,此时C项目就会传递到A项目中。
依赖排除
如果此时,A项目依赖B项目,无需依赖C项目,那么需要把自动传递的依赖排除掉,通过<exclusions>标签实现。
依赖调节原则
这个是maven解决传递依赖时jar包冲突问题的方法,maven会先根据第一原则进行选择,第一原则不成,则按第二原则处理。
(1)第一原则:路径近者优先原则
A-->B-->C-->D-->X(1.6)
E-->D-->X(2.0)
使用X(2.0),因为其路径更近
(2)第二原则:第一声明者优先原则。就是如果路径相同,maven 默认配置在前面的优先使用
A-->B --> X(1.6)
C-->D--> X(2.0)
这样就是路径相同,那么如果A在前面,C在后面,则使用X(1.6)
4. 构建生命周期
一个构建生命周期是一组精心组织的有序的阶段
每一个阶段执行预先定义的“动作”
- 编译
- 打包
- 部署
- ...
这些“动作”会根据项目的类型进行选择
Maven拥有三套相互独立的生命周期,它们分别为clean、default和site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。
每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和maven最直接的交互方式就是调用这些生命周期阶段。
较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。
5. 命令
需要在pom.xml所在目录中执行以下命令。
mvn compile(mvn compile -U 强制更新)
完成编译操作,执行完毕后,会生成target目录,该目录中存放了编译后的字节码文件。
-U 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默认以天为单位检查更新,而持续集成的频率应该比这高很多。
mvn clean
执行完毕后,会将target目录删除。
mvn test
完成单元测试操作,执行完毕后,会在target目录中生成三个文件夹:surefire、surefire-reports(测试报告)、test-classes(测试的字节码文件)。
mvn package
完成打包操作,执行完毕后,会在target目录中生成一个文件,该文件可能是jar、war。
mvn install
完成将打好的jar包安装到本地仓库的操作,执行完毕后,会在本地仓库中出现安装后的jar包,方便其他工程引用。
mvn clean compile命令
组合指令,先执行clean,再执行compile,通常应用于上线前执行,清除测试类。
mvn clean test命令
组合指令,先执行clean,再执行test,通常应用于测试环节。
mvn clean package命令
组合指令,先执行clean,再执行package,将项目打包,通常应用于发布前。
执行过程:
- 清理————清空环境
- 编译————编译源码
- 测试————测试源码
- 打包————将编译的非测试类打包
mvn clean install命令
cmd 中录入 mvn clean install 查看仓库,当前项目被发布到仓库中,组合指令,先执行clean,再执行install,将项目打包,通常应用于发布前。
执行过程:
- 清理————清空环境
- 编译————编译源码
- 测试————测试源码
- 打包————将编译的非测试类打包
- 部署————将打好的包发布到资源仓库中
不要忘了clean:clean能够保证上一次的构建的输出不会影响到本次构建
指令 | 作用 | |
---|---|---|
编译:mvn compile | src/main/java目录java源码编译生成class (target目录下) | |
测试:mvn test | src/test/java 目录编译 | |
清理:mvn clean | 删除target目录,也就是将class文件等删除 | |
打包:mvn package | 生成压缩文件:java项目#jar包;web项目#war包,也是放在target目录下 | |
安装:mvn install | 将压缩文件(jar或者war)上传到本地仓库 | |
部署 | 发布:mvn deploy | 将压缩文件上传私服 |
package/install/deploy区别
-
package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库;
-
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库;
-
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
6. maven使用中的常见问题
在maven多模块项目中,内部模块之间常常存在一些互相依赖,假设模块B依赖模块A,我修改了A,增加了一些功能,然后从B中调用这些功能却调用不了,这是什么原因?
修改完A之后并没有将其install或者deploy,所以B依赖的还是修改之前的A,然后B就无法体现A中功能的变更,综上,在开发maven项目时要养成一个好习惯,修改完一个模块之后立即将其install或者deploy,然后再去开发下一个模块。
网友评论