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. BZOJ2348: [Baltic 2011]Plagiarism

    2348: [Baltic 2011]Plagiarism Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 304  Solved: 141[Submit ...

  2. ☀【offset() / position()】

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8& ...

  3. LightOJ 1356 Prime Independence 二分图最大独立集,HK算法

    这个题唯一需要说的就是普通的匈牙利算法是O(nm)的,过不了 然后HK算法可以O(n^0.5m),这个算法可以每次找很多同样长度的最短增广路 分析见:http://www.hardbird.net/l ...

  4. POJ -- 3233 求“等比矩阵”前n(n <=10^9)项和

    Matrix Power Series   Description Given a n × n matrix A and a positive integer k, find the sum S =  ...

  5. acm位运算应用 搜索

    acm位运算应用 搜索 搜索    此处不讲题目,只讲位运算是怎样在这些题中实现和应用的.由于搜索题往往是基于对状态的操作,位运算往往特别有效,优化之后的效果可以有目共睹.    例1.POJ 132 ...

  6. Ruby应用记录:修改文件中某个字符串

    #修改android客户端中服务器地址的默认值为对应环境的服务器地址 #!/usr/bin/ruby ostr="192.168.88.95:8088" nstr="19 ...

  7. 改进的SMO算法

    S. S. Keerthi等人在Improvements to Platt's SMO Algorithm for SVM Classifier Design一文中提出了对SMO算法的改进,纵观SMO ...

  8. vim recording

    大家是否有这种经验,“不知道为什么按出recording状态,按ESC貌似无法直接退掉”的情况,个人已经有过好几次了.与其出来烦人还不如了解它,昨天我就花了点时间学习recording.怎么说,还是有 ...

  9. 【Java基础】static关键字的理解

    修饰范围: 可以修饰成员变量和成员方法.静态的特点: A:随着类的加载而加载 B:优先于对象存在 C:被类的所有对象共享 这其实也是我们判断该不该使用静态的依据. 举例:饮水机和水杯的问题思考可通过类 ...

  10. HW4.37

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