何为Maven坐标
是Maven定义的一组规则,世界上任何一个构建都可以使用Maven坐标唯一标识,Maven坐标的元素包括groupId,artifactId,version,packging,classifier。只需要提供正确的坐标信息,Maven就能找到对应的构建。
坐标详解
坐标定义例子:
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>
groupId:定义当前Maven项目隶属于的实际项目
artifactId:该元素定义实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀
version:该元素定义Maven项目当前所处的版本
packaging:该元素定义Maven项目的打包方式
classifier:该元素用来帮助定义构建输出的一些附属构建
依赖详解
- type:依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,默认值为jar
- 依赖范围:依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行classpath)的关系,Maven有以下几种依赖范围:
2.1 compile:编译测试范围。如果没有指定,就会默认使用该依赖范围。使用此依赖的Maven依赖,对于编译,测试,运行三种classpath都有效
2.2 test:测试依赖范围,此依赖只对测试classpath有效
2.3 provided:已提供依赖范围,此依赖范围对编译和测试classpath有效
2.4 runtime:运行时依赖范围,此依赖对于测试和运行有效
2.5 system:系统依赖范围,依赖范围和provided完全一致,但是使用此依赖时必须通过systemPath元素显示的指定依赖文件的路径,代码示例如下:
<dependency>
<groupId>java.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
- 传递性依赖和依赖范围
第一直接依赖的范围和第二直接依赖的范围决定了传递性依赖的范围。如下表所示,最左边一列表示第一直接依赖范围,最上面一行表示第二直接依赖范围,中间的交叉单元格则表示传递性依赖范围:
compile | test | provided | runtime | |
---|---|---|---|---|
compile | compile | -- | -- | runtime |
test | test | -- | -- | test |
provided | provided | -- | provided | provided |
runtime | runtime | -- | -- | runtime |
为了帮助理解,举个例子:account-email项目有一个com.icegreen:greenmail:1.3.1b的直接依赖我们说这是第一直接依赖,其依赖范围是test;而greenmail又有一个javax.mail:mail:1.4的直接依赖,我们说这是第二直接依赖,其依赖范围为compile。显然,javax.mail:mail:1.4是account-email的传递性依赖,对照表可以知道,当第一直接依赖范围为test,第二直接依赖范围是compile的时候,传递性依赖范围是test,因此,javax.mail:mail:1.4是account-email的一个范围是test的传递性依赖
依赖操作
-
依赖调解,当传递性依赖造成问题的时候,我们就需要清楚的知道该传递性依赖时从那条依赖路径引入的
Maven调解的两大原则:
1.1 路径最近者优先
1.2 第一声明者优先,顺序最靠前的那个依赖优胜 -
可选依赖使用<optional>元素表示依赖为可选依赖,当依赖为可选依赖时,该依赖只对本项目产生影响,如若别的项目依赖本项目,不会依赖本项目的可选依赖。使用可选依赖的原因是某一个项目实现了多个特性,在面向对象设计中,有个单一职责型原则,意指一个类应该只有一项职责,而不是糅合太多的功能
-
排除依赖
假想情况:当前项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另外一个类库的SNAPSHOP版本,那么这个SNAPSHOP就会成为当前项目的传递性依赖,而SNAPSHOP的不稳定性会直接影响到当前项目,这时候就需要排除掉该SNAPSHOP,并且在当前项目中声明该类库的某个正式的发布版本
解决方法:代码中使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusions子元素,因此可次排除一个或者多个传递性依赖
代码示例如下:
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-c</artifactId>
</exclusion>
</exclusions>
</dependency>
- 优化依赖
4.1 mvn dependency:list,查看当前项目的已解析依赖
4.2 mvn dependency:tree,查看当前项目的依赖树
使用上面两个命令可以帮助我们详细了解项目中所有依赖的具体信息,在此基础上,还有dependency:analyze工具可以帮助分析当前项目的依赖
注:最好是显示的声明任何项目中直接用到的依赖
仓库的分类
-
本地仓库
不管Linux还是Windows上,每个用户在自己的目录下都有一个路径名为.m2/respository/的仓库目录。以.开头的文件或目录默认是隐藏的,可以使用ls-a命令显示隐藏文件或目录
有时候,用户会想要自定义本地仓库目录地址,可以编辑文件~/.m2/settings.xml,设置localRepository元素的值为想要的仓库地址
Install插件的install目标将项目的构建输出文件安装到本地仓库 -
私服
私服是一种特殊的远程仓库,为了节省宽带和时间,应该在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库。内部的项目还能部署到私服上供其它项目使用,一些无法外部仓库下载到的构件也能从本地上传到私服上供大家使用。
私服主要的作用有: 节省自己的外网宽带,加速Maven构建,部署第三方构建,提高稳定性,增强控制,降低中央仓库的负荷
远程仓库的配置
- 在respository元素下,可以使用respository子元素声明一个或者多个远程仓库
- 对于releases和snapshots来说,除了enabled,塔门还包含另外两个子元素uodatePolicy和checksumPolicy
2.1 updatePolicy:配置Maven从远程仓库检查更新的频率
2.2 checksumPolicy:配置Maven检查检验和文件的策略
2.3 代码示例:
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</snapshots>
- 远程仓库的认证需要在settings.xml中配置用户名和密码
<servers>
<server>
<id>my-proj</id>
<username>repo-user</username>
<password>repo-pwd</password>
</server>
</servers>
- 部署至远程仓库,distributionManagement包含repository和snapshotRepository子元素,前者表示发布版本构建的仓库,后者表示快照版本的仓库。id为该远程仓库的唯一标识,name是为了方便人阅读,关键的url表示该仓库的地址,部署到配置的远程仓库命令是mvn clean deploy
<distributionManagement>
<repository>
<id></id>
<name></name>
<url></url>
</repository>
<snapshotRepository>
<id></id>
<name></name>
<url></url>
</snapshotRepository>
</distributionManagement>
文章仅供参考,代码并不是全正确,只需要知道在对应的情况,可以做对应的处理,代码是变化的,我相信原理不变
网友评论