Maven学习笔记
Maven学习笔记
1.环境配置
已经配置过JAVA环境及Maven环境变量的配置工作
mvn- v
查看当前mvn版本及系统环境状态
mvn help:system
打印出所有的JAVA系统属性和环境变量
~/.m2
~
代表用户目录.m2
文件夹下有Maven的全部资源文件
m2eclipse插件
详情参考另一篇Maven博客中插件安装方法Maven
组件用途参考P10-P11
不要使用ME自带的Maven插件
2.入门使用
编写pom
POM(Project Object Model,项目对象模型)
1 |
|
groupId
定义了项目属于哪个组
artifactId
定义了当前Maven项目在组中唯一的ID
version
项目版本,SNAPSHOT
表示快照,项目处于开发中
name
一个对于用户更为友好的项目名称
Maven优点,项目对象模型最大程度地与实际代码相独立,解耦或者正交性。
Helloworld
编写测试代码
加入junit依赖
1 | <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"> |
mvn clean compile
项目根目录下执行后进行项目编译mvn clean test
Maven测试命令,先自动执行项目主资源处理,主代码编译,测试资源处理,测试代码编译工作。mvn clean package
默认打包类型为jar,即jar插件的jar目标将项目的主代码打包成一个 项目名.jar
的文件。mvn clean install
复制被打包的jar到其他的项目中需要安装。
在ME中使用maven项目操作依旧参照上篇博客
坐标和依赖
一个构件必须明确定义自己的坐标,一组Maven坐标是通过一些元素定义的:groupId
artifactId
version
packaging
| 可选classifier
| 不能直接定义
groupId
当前Maven项目隶属的实际项目。一个实际项目往往会被划分成很多模块。只定义到组织级别。
artifactId
定义实际项目中的一个Maven项目。
version
版本。
packaging
打包方式,默认为jar。
classifier
帮助定义构建输出的一些附属构件。
依赖范围
Compile
编译依赖范围。默认值,对于编译、测试、运行三种classpath都有效。Test
测试依赖范围。典型的例子是JUnit,只在编译测试代码及运行测试的时候才需要。Provided
已提供依赖范围。典型例子是servlet-api,对于编译和测试classpath有效,但在运行时无效。Runtime
运行时依赖范围。典型例子是JDBC驱动实现,对于测试和运行classpath有效,但在编译主代码时无效。System
系统依赖范围。必须通过systemPath元素显式地置顶依赖文件的路径。由于此依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植。
1 | <dependency> |
Import
导入依赖范围。不会对三种classpath产生实际的影响。
依赖范围(Scope) | 对于编译classpath有效 | 对于测试classpath有效 | 对于运行时classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-core |
test | - | Y | - | JUnit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | JDBC驱动实现 |
system | Y | Y | - | 本地的,Maven仓库之外的类库文件 |
传递性依赖
Maven会自动添加依赖关系,如使用Spring-Framwork的时候不用考虑它依赖了什么,也不用担心引入多余的依赖。
传递性依赖和依赖范围
假设A依赖于B,B依赖于C,我们说A对于B是第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。
下表左边一列表示第一直接依赖范围,最上一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围:
- | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
依赖调解
有时候我们只关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。
Maven依赖调解的第一原则:路径最近者优先。
例如:
项目A有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0)
其中X(1.0)的路径长度为3,X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
Maven依赖调解的第二原则:第一声明者优先。
在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。
例如:
项目A有以下依赖关系:A->B->Y(1.0)、A->C->Y(2.0),Y(1.0)和Y(2.0)依赖路径长度是一样的,都是2。顺序最靠前的那个依赖优胜。
可选依赖
假设有这样一个依赖关系,项目A依赖于项目B,B依赖于项目X和Y,B对于X和Y的依赖都是可选依赖:A->B、B->X(可选)、B->Y(可选)。根据传递性依赖的定义,如果所有这三个依赖的范围都是compile,那么X、Y就是A的compile范围传递性依赖。然而,由于这里X、Y是可选依赖,依赖将不会得以传递,换句话说,X、Y将不会对A有任何影响。
可能项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。比如B是一个持久层隔离工具包,支持多种数据库,构建时需要两种数据库的驱动程序,但在使用这个工具包的时候,只会依赖一种数据库。
排除依赖
传递性依赖会给项目隐式的引入很多依赖,这极大地简化了项目依赖的管理,但是有些时候这种特性也会带来问题。
例如,当一个项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另外一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性就会直接影响到当前的项目。
1 | <project> |
用 exclusions
元素声明排除依赖, exclusions
可以包含一个或者多个 exclusion
子元素,因此可以排除一个或者多个传递性依赖。
归类依赖
在升级项目的时候只需要修改一处,类似于配置文件。
1 | <project> |
优化依赖
Maven会自动解析所有项目的直接依赖和传递依赖,并且根据规则正确判断每个依赖的范围,对于一些依赖冲突,异能进行调节,以确保任何一个构件只有唯一的版本在依赖中存在。最后得到的那些依赖被称为已解析依赖。
依赖树。
使用Maven构建Web应用
指定打包方式为war
使用Cargo实现自动化部署
cargo-maven2-plugin
主要服务于自动化部署
部署至本地Web容器
standalone
模式。Cargo会从Web容器的安装目录复一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。existing
模式。用户需要指定现有的Web容器配置目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置。
1 | <plugin> |
部署至远程Web容器
1 | <plugin> |