Maven的核心概念有 坐标、依赖、仓库、生命周期、插件等。
1 Maven坐标
1.1 本项目的坐标
- groupId: 必须。项目组名称,定义当前Maven项目所隶属的实际项目,通常与域名反向一一对应,与Java包名表示方式类似
- artifactId: 必须。项目名称
- version: 必须。版本
- packaging: (可选,没写则为jar)。打包方式,jar、war等
- classifier (不能直接定义)。帮助定义构建输出的附属构件
需要说明的是每个工程应该只有一个 POM 文件。
- 所有的 POM 文件需要 project 元素和三个必须的字段:groupId, artifactId,version。这三个坐标即所谓的GAV坐标。
- 在仓库中的工程标识为 groupId:artifactId:version
- POM.xml 的根元素是 project,它有三个主要的子节点:
| 节点 | 描述 |
|---|---|
| groupId | 这是工程组的标识。它在一个组织或者项目中通常是唯一的。例如,一个银行组织 com.company.bank 拥有所有的和银行相关的项目。 |
| artifactId | 这是工程的标识。它通常是工程的名称。例如,消费者银行。groupId 和 artifactId 一起定义了 artifact 在仓库中的位置。 |
| version | 这是工程的版本号。在 artifact 的仓库中,它用来区分不同的版本。例如: com.company.bank:consumer-banking:1.0 com.company.bank:consumer-banking:1.1. |
1.2 项目的依赖的坐标
- groupId: 必须。依赖的组名称
- artifactId: 必须。依赖的工程名称
- version: 必须。版本
- type: (可选,没写则为jar),该依赖的类型
- scope (可选,没写则为compile),依赖的范围:compile、test、provided、runtime、system、import,用来控制在 编译classpath、测试classpath、运行classpath 三种classpath中依赖是否起作用。更多可参阅:maven dependency scope。
1.compile: 默认编译依赖范围。对于编译,测试,运行三种classpath都有效。
2.test:测试依赖范围。只对于测试classpath有效。
3.provided:已提供依赖范围。对于编译,测试的classpath都有效,但对于运行无效。因为容器已经提供,例如servlet-api,服务器如Tomcat会自带该api,所以程序不用将之打入包中。相当于compile,但是在打包阶段做了exclude的动作。
4.runtime:只对运行时有效。例如JDBC 驱动,项目代码只需要 jdk 提供的 jdbc 接口而不需要驱动,只有在执行测试和运行项目的时候才需要实现 jdbc 的功能。
5.system:从参与度来说,也provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,需要配合systemPath属性使用。
- optional (可选,没写则为必选)标记依赖是否可选,一般不用,因为按面向对象设计单一职责原则,一个类应只有一个职责而非糅合太多功能。
- exclusions (可选),用来排除依赖的传递性。只需要指定 groupId 和 artifactId
当Maven通过这些坐标无法从中心仓库获取该组件时,可以通过下面的方法处理:
- 用安装插件安装本地依赖,命令:
mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
- 创建你自己的仓库,并部署它
- 设置依赖scope到system,并定义一个systemPath,但这个不推荐
2 Maven依赖
2.1、添加不在repository中的依赖
法1:(不太可行)
先下载jar包并放在项目下,然后作为dependency通过system scope加入pom。缺点:本地可运行,但使用jar-with-dependencies打包时该包将不会被包含。
1 <!--添加本地依赖--> 2 <dependency> 3 <groupId>org.apache.kafka</groupId> 4 <artifactId>kafka_2.8.0</artifactId> 5 <version>0.8.1.1</version> 6 <scope>system</scope> 7 <systemPath>${project.basedir}/lib/kafka_2.8.0-0.8.1.1.jar</systemPath> 8 </dependency> 9 10 <!--即使借助如下的resources将本地包打入目标jar,也只是作为资源加入而不是作为依赖,所以还是找不到--> 11 <!-- 12 <build> 13 <resources> 14 <resource> 15 <targetPath>lib/</targetPath> 16 <directory>lib/</directory> 17 <includes> 18 <include>**/kafka_2.8.0-0.8.1.1.jar</include> 19 </includes> 20 </resource> 21 </resources> 22 </build> 23 -->