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. Com和DCOM

    COM,DCOM原理及应用 1.DCOM COM的进程透明特性表现在组件对象和客户程序即可以拥有各自的进程空间,也可以共享同一个进程空间,COM负责把客户的调用正确传到组件对象中,并保证参数传递的正确 ...

  2. 【转】自定义垂直的UISlider

    原文网址:http://www.cocoachina.com/bbs/read.php?tid=96282 怎样自定义垂直的UISlider? UISlider弄成垂直的代码就是:slider.tra ...

  3. 【转】VC中对文件的读写

    原文网址:http://www.cnblogs.com/LJWJL/archive/2012/10/06/2712466.html 注意: 1.由于C是缓冲写 所以要在关闭或刷新后才能看到文件内容 2 ...

  4. 使用IIS配合VS调试

    当我们使用Visual Studio调试(Debug)的时候,通常我们会选择VS自带的ASP.NET Developerment Server(也是默认选项),当第一次调试的时候(按F5或Ctrl+F ...

  5. c#抓取当前电脑显示分辨率

    using System.Windows.Forms; 获取屏幕分辨率            int SH = Screen.PrimaryScreen.Bounds.Height;          ...

  6. oracle rac存储安装

    oracle rac 10.2 的在 linux 上的存储选项 博客分类: Oracle OracleLinux项目管理配置管理  Oracle 集群需要存储的软件和数据 项目 内容 最少磁盘空间 C ...

  7. Scala学习笔记(三)类层级和特质

    无参方法 功能:将方法的定义转换为属性字段的定义: 作用范围:方法中没有参数,并且方法仅能通过读取所包含的对象属性去访问可变状态,而不改变可变状态,就可使用无参方法: 例子: abstract cla ...

  8. Weka 入门2

    现在我们介绍使用Weka来对数据进行分类.对数据进行分类,我们必须先指定那一列作为预测类别.因为数据文件格式的问题,类别一般都是最后一列属性.我们可以使用setClassIndex来设置类别.然后我们 ...

  9. 用户名 不在 sudoers文件中,此事将被报告

    解决方法: 1.通过编辑器来打开/etc/sudoers 2.直接使用命令visudo 打开sudoers后,如下加上自己的帐号保存后就可以了. # User privilege specificat ...

  10. GridControl 选择列、复选框全选(上)

    说明: GirdControl 中添加一列,这一列不是写在数据库中的,而是代码中添加的. 图示: 底层类代码: #region GridControl 全选 /// <summary> / ...