Maven是目前比较主流的项目管理工具之一,当然Gradle也是其中之一。它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
- pom:项目对象模型 (Project Object Model),项目的属性、依赖、构建、配置信息等都被抽象到项目对象模型里,定义了项目的基本信息;
Maven的特点:
- 微内核:大部分功能通过插件实现,主要用于XML文件的解析、管理生命周期;
- 约定优于配置。
Maven构建的步骤:
- 清理:清理以前旧的class文件
- 编译
- 测试
- 报告
- 打包
- 安装
- 部署
IDEA导入Maven项目,直接File–>open…–>选择pom.xml文件即可导入Maven工程,具体的依赖可以通过IDEA边界菜单栏Maven Project中的Dependencies。
1.1 坐标和依赖
maven中任何一个依赖、插件、项目的输出都可以叫做构件,任何一个构件都可以用一个规则来唯一标记,这个规则就是坐标,主要由以下元素构成(前三者通常是一个依赖的必要元素):
- groupId:必要属性,如果插件是maven官方提供了,那么此时可以省,定义当前Maven项目隶属的实际项目,通常取用反向域名;
- artifactId:必要属性,定义实际项目中中具体模板,通常就取实际的模块名字;
- version:必要属性,定义Maven项目当前所处的版本,如果继承自父类,那么这个属性可省自动使用父类版本;
- packaging:非必要,Maven的打包方式默认是jar,可以自己手动改;
- classifier:非必要,定义构件输出的一些附属构件,不常用,不能直接定义,由插件帮助生成;
- type:依赖的类型
- scope:依赖的范围
- optional:标识依赖是否可选
- exclusions:用来排除传递性依赖
<scope>
:依赖范围,maven的classpath总共有3套,编译一套、编译和执行测试一套、实际运行一套,默认参数是compile,三套classpath都有效;test,测试范围;provided:编译和测试有效;runtime:测试和运行范围;system:系统范围,慎用;他们三个作用的范围如下表所示:
scope | 编译 | 测试 | 运行 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | Spring-core |
test | - | Y | - | Junit |
provided | Y | Y | - | Servlet-Api |
runtime | - | Y | Y | JDBC驱动 |
system | Y | Y | - | 本地的,Maven仓库之外的类库文件 |
maven具备传递性依赖机制,maven会解析各个直接依赖的POM。下面是一个例子,最左边的一列表示A对B的依赖范围,最上面是B对C的依赖范围,那么A对C的依赖范围:
- | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
依赖调节:A和B依赖同一构件的不同版本,而C依赖同时依赖A和B,那么C对于同一构件的不同版本将出现冲突,两种解决方式:
- 短路优先:如果A–>B–>C–>X.jar,然后A–>D–>X.jar,那么后者优先解析;
- 声明优先:如果路径的长度相同,那么谁先声明就先解析。
归类依赖:最常见的就是版本号<version>
配置。
1.2 仓库
仓库:远程仓库可以在代码中进行手动配置,并且可以配置多个,比如:
<!-- 配置spring 仓库 ,用于下载中央仓库、私服 全部都找不到某个jar -->
<repositories>
<repository>
<id>spring-snapshots</id>
<name