1. 坐标

Maven坐标为各种构件引入了秩序,任何一个构件都有必须明确定义自己的坐标,而一组Maven坐标是通过一些元素定义的,它们是groupId, artifactId, version, packaging, classifier。

下面简单介绍一下这几个标签

1) groupId

定义当前Maven项目隶属的实际项目,当然跟实际项目之间并不是一对一的关系。其命名方式与Java包名的方式类似,通常与域名反向一一对应。例如org.sonatyp.nexus。在后面的聚合里面可以看到,同一项目的不同模块,拥有相同的groupId

2)artifactId

定义实际项目中的一个Maven项目(或者模块),推荐的做法是使用实际项目名称作为artifactId的前缀,这样的作用是当不同的项目拥有同样的模块名称时方便区分,如foo-core-1.2.jar, bar-core-1.2.jar等。

3)version

定义Maven项目当前所处的版本,Maven定义了一整套版本规范,以及快照的概念。

上面三个元素是必须定义的

4)packaging

定义项目的打包方式,包括pom,war,jar等,默认为jar.

5)classifier

用来帮助定义构建输出的一些附属构件。附属构件与主构件对应,例如foo-core.1.2.jar,还可以通过插件的方式生成foo-core-1.2-javadoc.jar等。该标签不能直接定义,因为附属构件不是由项目直接默认生成的,而是由附加的插件生成。

2.依赖

pom.xml 根元素project下的dependencies可以配置一个或多个dependency元素,以声明一个或多个项目依赖。(何为依赖?其实就是引用……)

每个依赖可以包含的元素有:

1)groupId, artifactId, version。基本坐标,上面已描述

2)type 依赖的类型,对应构件的packaging.大部分情况下,该元素不必声明,默认值为jar.

3)scope 依赖的范围

首先要知道,Maven在编译项目主代码的时候,需要使用一套classpath(简称编译classpath);在编译和执行测试的时候会使用另外一套classpath(简称测试classpath);最后,在实际运行Maven项目时,又会使用另外一套classpath(简称运行classpath,其实不是很懂,运行期间还用到Maven么?)

依赖范围就是用来控制依赖与这三种classpath之间的关系的

compile:编译依赖范围,默认的范围,对于三种classpath都有效。

test:测试依赖范围,只对于测试classpath有效。

provided:已提供依赖范围,对于编译和测试classpath有效,在运行时无效。

runtime: 运行时依赖范围,对于测试和运行时classpath有效,在编译时无效。

system:系统依赖范围,该依赖与provided的范围一致,但其依赖必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此慎用。如下:

<dependency>

  <groupId>javax.sql</groupId>

  <artifactId>jdbc-stdext</artifactId>

  <version>2.0</version>

  <scope>system</scope>

  <systemPath>${java.home}/lib/rt.jar</systemPath>

</dependency>

import:导入依赖范围。后续再介绍。

4)exclusions 排除传递性依赖

依赖是会传递的,例如A依赖了B,B依赖了C,那么A和C之间便是传递性依赖。如果A实际上不需要依赖,那么可以通过此项将两者之间的依赖切断。

依赖范围不仅可以控制依赖与三种classpath的关系,还可以对传递性依赖产生影响。

首先假设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

5)optional 依赖是否可选

A->B->X(可选), A->B->Y(可选),根据传递性,假如所有这几个依赖范围都是compile,那么X Y就是A的compile范围传递性依赖,然而,由于这里X Y都是可选的,依赖将不会传递,也就是说,X Y将不会对A造成影响。

3.依赖调解

依赖传递机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关系项目直接依赖是什么。

假设有如下场景:A->B->C->X(1.0) ,A->D->X(2.0),现在X有两个版本,那么哪个版本会被Maven解析呢?

Maven依赖调解第一原则是:路径最近者会被解析,那么上例中,X(1.0)将会被解析。

再考虑一个场景:A->B->X(1.0),A->D->X(2.0),依赖的路径都是2,哪个版本会被解析呢?

Maven依赖调解第二原则是:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。在这个例子中,在A的POM文件,如果B比D先声明,那么X(1.0)将被解析使用。

4.最佳实践

1)排除依赖,不赘述

2)归类依赖

假设项目中有很多对Spring Framework的依赖(org.springframework:spring-core:2.5.6, org.springframework:spring-beans:2.5.6等),这些依赖都是来自同一项目的不同模块,因此版本是相同的,可以预见未来如果要升级,那么版本号也是要一起升级的。

可以通过Maven属性,定义一些变量,统一使用,类似代码中的常量。使用类似EL表示式的变量形式。

<project>

  ......

  <properties>

    <springframework.version>2.5.6</springframework.version>

  </properties>

  <dependencies>

    <dependency>

      <groupId>......</groupId>

      <artifactId>......</artifactId>

      <version>${springframework.version}</version>

    </dependency>

    ......

  </dependencies>

3)优化依赖

mvn dependency:list 查看项目已解析的构件的列表

mvn dependency:tree 查看项目依赖的构件的依赖树

mvn dependency:analyze 分析项目对依赖的使用情况。主要是两部分

首先是Used undeclared dependencies,项目中使用到的但没有显式声明的依赖。看似没有任何问题,实际上也隐藏风险。例如A->B->X(1.0),A用到了X(1.0)的接口,却又不显式声明,那么当B的依赖升级变成X(2.0),可能接口变更,A就有可能编译失败。

其次是Unused declared dependencies,未使用的,却声明了的依赖。由于这个命令只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它发现不了,所以不能草率删除,应进行分析。

Maven笔记(一)的更多相关文章

  1. maven笔记--持续更新

    笔记: 在创建maven项目的时候,如果用到servlet的时候,需要导入包,这时候,需要导入本地仓库的jar包,即依赖包.语法如下 <dependency> <groupId> ...

  2. Maven笔记---超详细

    显眼位置标注来源:此文章为B站课程黑马程序员Maven全套教程笔记,由本人整理. Maven简介 Maven的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM) POM (P ...

  3. maven笔记

      jar间接依赖:  被依赖的jar的范围要设置成compile,因发布会包含test范围依赖的jar包.   建立项目之间的联系:先在pom中设定依赖关系,然后可以引用了    .conf:  C ...

  4. Maven 笔记

    maven DOS 打包命令:maven项目 cd 进入项目根目录执行 mav clean package;

  5. 框架Maven笔记系列 一 基础

    主题:SpringMVC 学习资料参考网址: 1.http://www.icoolxue.com 2.http://maven.apache.org/ 1.Maven解决了什么问题? Maven基于项 ...

  6. maven笔记-入门(helloWorld)

    maven: pom.xml:文件 groupId,artifactId,Version定义了一个项目的基本坐标 groupId:定义了项目属于哪个组,往往与项目所在的组织和公司有关 artifact ...

  7. Maven笔记(二)仓库

    1.仓库布局 任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这就是Maven的仓库布局方式 路径与坐标的对应关系为:groupId/artifactId/version/ ...

  8. maven笔记学习

    一.修改setting.xml文件中的镜像 在导入他人项目或者在导入项目时,我们会出现在项目中不能识别maven配置的库文件的情况那么我们可以重新下载本地库, 首先我们可以修改我们安装的maven环境 ...

  9. maven笔记-将本地jar包打包进可执行jar中

    参考资料:http://www.cnblogs.com/richard-jing/archive/2013/01/27/Maven_localjar.html 使用本地jar <dependen ...

随机推荐

  1. apache开源项目--kylin

    Kylin 是一个开源的分布式的 OLAP 分析引擎,来自 eBay 公司开发,基于 Hadoop 提供 SQL 接口和 OLAP 接口,支持 TB 到 PB 级别的数据量. Kylin 是: 超级快 ...

  2. If-Modified-Since & If-None-Match

    google告诉网站站长:您的网络服务器支持 If-Modified-Since HTTP 标头.通过该功能,您的网络服务器可以告诉 Google 自上次抓取您的网站以来,内容是否已发生变化.该功能可 ...

  3. Using the Task Parallel Library (TPL) for Events

    Using the Task Parallel Library (TPL) for Events The parallel tasks library was introduced with the ...

  4. HDU 2191

    思路:简单动态规划,多重背包转化成0 1背包问题 #include<stdio.h> #include<string.h> int a[101][2001],rcw[2001] ...

  5. 修改SR4000自带软件,支持opencv

      /*----------------------------------------------------------------------------- * * 版权声明: * 可以任意转载 ...

  6. Codeforces Round #335 (Div. 2)B. Testing Robots解题报告

                                                                                               B. Testin ...

  7. 【原】计算机Tools vs 学习资料

    今天,给大家推荐一些比较使用的软件,主要从免费和好用两个角度考虑. 首先推荐一个网址"http://tool.oschina.net/",上面有非常好用的小工具,可以极大的方便我们 ...

  8. codeforce 621C Wet Shark and Flowers

    题意:输入个n和质数p,n个区间,每个区间可以等概率的任选一个数,如果选的这个区间和它下个区间选的数的积是p的倍数的话(n的下个是1),就挣2000,问挣的期望 思路:整体的期望可以分成每对之间的期望 ...

  9. shell常识总结

    #!/bin/bash cmd="ls -lt | grep ^d | awk 'NR==1 {print $9}'" $cmd 这是一个获取文件夹名字的脚本,但是却提示: ls: ...

  10. HW4.41

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...