Maven pom.xml与settings.xml详解

pom.xml与settings.xml

pom.xml与setting.xml,可以说是Maven中最重要的两个配置文件,决定了Maven的核心功能,虽然之前的文章零零碎碎有提到过pom.xml和settings.xml里面的内容,但都是大略带过,学习与研究地并不细致,本文的目的就是详细研究下这两个Maven重要的配置文件,从这两个配置文件可以牵出非常多的Maven话题。

 Maven坐标

首先谈一下为什么要使用Maven坐标。

Maven世界拥有数量非常巨大的构件,也就是平时使用的一些jar、war等文件,在Maven为这些构件引入坐标概念之前,我们无法使用任何一种方式来唯一标识所有这些构件。因此,如果需要使用Spring依赖,那么就去Spring官网寻找;如果需要使用log4j依赖,那么又去Apache官网寻找。又因为各个网站风格迥异,大量时间花费在了搜索和浏览网页的工作上。没有统一规范与法则,工作就无法自动化,重复性的劳动本来就应该交给机器来做。

Maven定义了这样一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识,Maven坐标元素包括groupId、artifactId、version、packaging、classifier,现在只要我们提供正确的元素坐标,Maven就能找到对应的构件。至于去哪里下载,Maven本身内置了一个中央仓库的地址"http://repo1.maven.org/maven2",该中央仓库包含了世界上绝大部分流行的开源项目构件,Mavne会在需要的时候去那里下载,当然也可以配置自己的中央仓库地址,去自己的中央仓库下载构件。

举个例子,Spring的context:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.2.6.RELEASE</version>
</dependency

看一下下属的各个元素:

  • groupId:定义当前Maven项目隶属的实际项目。由于Maven项目和实际项目未必是一对一的关系,比如SpringFramework这个实际项目可能对应的Maven项目有很多,像core、context、expression等等,因此groupId不应该对应项目隶属的公司或组织,否则artifact将很难定义
  • artifactId:定义实际项目中的一个Maven模块,推荐的做法是使用实际项目名称作为artifactId的前缀,这样会很方便去寻找实际构件
  • version:定义Maven项目当前所处的版本,如上面的spring-context就是4.2.6的,RELEASE表示正式发行版本
  • packing:定义Maven项目的打包方式,这项不是必须的,没列出来,不定义默认就是jar的打包方式
  • classifier:帮助定义构件输出的一些附属构件,比如xxx-javadoc.jar、xxx-sources.jar,附属构件与主构件对应,这项是不能直接定义的

Maven坐标的概念大致上就是这样,理解Maven坐标,是理解Maven很重要的一步。

传递性依赖

什么是传递性依赖,以Spring举一个例子。使用Spring的时候会依赖于其他开源的类库,此时有两种做法:

1、下载一个很大的.zip包,里面包含了所有Spring的jar,但是这么做往往就引入了许多不必要的依赖

2、只下载spring相关的.zip包,不包含依赖,实际使用的时候根据出错信息,加入需要的其他依赖

显然这两种做法都非常麻烦,Maven的传递性依赖机制很好地解决了这一问题。打开spring-core-4.1.0.RELEASE的pom.xml,我截取一段关键部分:

<dependencies>
  <dependency>
   <groupId>commons-codec</groupId>
   <artifactId>commons-codec</artifactId>
   <version>1.9</version>
   <scope>compile</scope>
   <optional>true</optional>
  </dependency>
  <dependency>
   <groupId>commons-logging</groupId>
   <artifactId>commons-logging</artifactId>
   <version>1.1.3</version>
   <scope>compile</scope>
  </dependency>
  ...
</dependencies>

比如A项目依赖了spring-core,spring-core又依赖了commons-codec和commons-logging,那么commons-codec和commons-logging就是A项目的一个传递性依赖。有了传递性依赖机制,在使用spring-core的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖,Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中去。

有了传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面在大部分情况下我们只需要关心项目的直接依赖是什么而不用考虑这些直接依赖会引入什么传递性依赖,不过有时候传递性依赖也会有一些问题,此时我们就需要清除地知道该传递性依赖是从哪条路径引入的,这就叫依赖调解,依赖调解主要有两点原则:

1、A->B->C->X(1.0),A->D->X(2.0),此时两条依赖路径上有两个版本的X,此时遵循路径最近者优先,因此X(2.0)将被解析使用

2、A->B->Y(1.0),A->C->Y(2.0),Y(1.0)和Y(2.0)的依赖长度是一样的,从Maven2.0.9开始,此时遵循第一声明者优先,即顺序最靠前的那个依赖优先

排除依赖

传递性依赖会给项目隐式地引入很多依赖,这极大地简化了项目依赖的管理,但是有时候这种特性也会带来问题。比如有种情况:

当前项目依赖A,A由于某些原因依赖了另外一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,二SNAPSHOT的不稳定性将直接影响到当前的项目,此时就需要排除该SNAPSHOT,并且在当前项目中声明该类库的某个正式发布的版本

排除依赖很简单,看一下写法:

<dependency>
  <groupId>com.alibaba.rocketmq</groupId>
  <artifactId>rocketmq-client</artifactId>
  <version>3.2.7</version>
  <exclusions>
    <exclusion>
      <groupId>apache-lang</groupId>
      <artifactId>commons-lang</artifactId>
    </exclusion>
  </exclusions>
</dependency>

这里我引入了rocketmq的依赖,但是我不想依赖rocketmq里面的apache-lang,而想要自己引入依赖,所以我就把apache-lang给排除了。

这里需要注意的是,声明exclusion的时候只需要groupId和artifactId即可,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。

settings.xml

settings.xml里面是Maven的基本配置,元素比较多,逐一看一下

1、proxy

proxy表示Maven的代理,看一下写法:

<proxies>
  <proxy>
   <id>optional</id>
   <active>true</active>
   <protocol>http</protocol>
   <username>proxyuser</username>
   <password>proxypass</password>
   <host>proxy.host.net</host>
   <port>80</port>
   <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
  </proxy>
</proxies>

需要proxy是因为很多时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问因特网。这种情况下,就需要为Maven配置HTTP代理,才能让它正常访问外部仓库,以下载所需要的资源。proxies下可以配置多个proxy元素,如果声明了多个proxy元素,则默认情况下第一个被激活的proxy会生效。active为true表示激活该代理,protocol表示使用的代理协议,当然最重要的是指定正确的主机名(host)和端口(port),如果代理服务器需要认证则配置username和password,nonProxyHost元素表示指定哪些主机名不需要代理,可以用"|"分隔多个主机名,也支持通配符"*"。

2、repository

repository表示Maven的中央仓库,因为尽管默认的远程仓库中的构件非常庞大,但是总归会有不满足我们需求的时候,这时候就要用到别的中央仓库了。看一下写法:

<repository>
  <id>public</id>
  <name>local private nexus</name>
  <url>http://192.168.1.6:8081/nexus/content/groups/public</url>
  <releases>
    <enabled>true</enabled>
  </releases>
  <snapshots>
    <enabled>false</enabled>
  </snapshots>
</repository>

可以声明多个repository。id必须是唯一的,尤其注意,Maven自带的中央仓库使用的id为central,如果其他仓库声明也用该id,就会覆盖中央仓库的配置。releases和snapshots比较重要,前者表示开启仓库的发布版本下载支持,后者表示关闭仓库的快照版本下载支持,这样一来,Maven就会去仓库下载发布版本的构件而不会下载快照版本的构件了。

3、server

大部分远程仓库无须认证就可以访问,但是有时候处于安全方面的因素考虑,需要提供认证信息才能访问一些远程仓库,处于安全考虑,认证信息一般只放在settings.xml中,server就是认证元素。看一下配置:

<server>
  <id>nexus-releases</id>
  <username>deployment</username>
  <password>deployment</password>
</server>

这里的关键是id,这个id必须与需要认证的repositiry元素的id完全一致才行,换句话说,正式这个id将认证信息和仓库配置联系在了一起。

4、mirror

如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为仓库X是仓库Y的一个镜像(mirror),换句话说,任何一个可以从Y中获取到的构件够可以从X中获取到。举个例子,"http://maven.net.cn/content/groups/public/"是中央仓库"http://repo1.maven.org/maven2/"在中国的镜像,由于地理位置的因素,该镜像往往能够提供比中央仓库更快的服务,这就是为什么要使用mirror的原因。

看一下mirror的配置:

<mirror>
  <id>nexus</id>
  <name>internal nexus repository</name>
  <url>http://192.168.1.6:8081/nexus/content/groups/public</url>
  <mirrorOf>*</mirrorOf>
</mirror>

该例子中,mirrof为*,表示该配置为所有中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像。另外三个元素id、name、url与一般仓库配置无异,表示该镜像仓库的唯一标识符、名称以及地址。类似的,如果该镜像需要认证,也可以基于该id配置仓库认证。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • maven中pom.xml详细介绍

    POM 代表工程对象模型.它是使用 Maven 工作时的基本组建,是一个 xml 文件.它被放在工程根目录下,文件命名为 pom.xml. POM 包含了关于工程和各种配置细节的信息,Maven 使用这些信息构建工程. POM 也包含了目标和插件.当执行一个任务或者目标时,Maven 会查找当前目录下的 POM,从其中读取所需要的配置信息,然后执行目标.能够在 POM 中设置的一些配置如下: project dependencies plugins goals build profiles pr

  • 配置pom.xml用maven打包java工程的方法(推荐)

    最近由于项目需要,研究了一下maven的打包,项目要做到 1,生成3个目录/lib,/conf,/bin目录 2,把所有的jar目录编译.拷贝到/lib目录(包括maven的jar包和lib目录下的jar,以及编译的jar包) 3,把所有的启动脚本从工程根目录拷贝到/bin目录 4,把所有的配置文件从src/main/resources拷贝到/conf 下面是配置的pom.xml,我把相关的配置都加了注释,一看就能明白,把build节点拷贝到你们的项目中,就基本可以用了:) <project x

  • Maven pom.xml与settings.xml详解

    pom.xml与settings.xml pom.xml与setting.xml,可以说是Maven中最重要的两个配置文件,决定了Maven的核心功能,虽然之前的文章零零碎碎有提到过pom.xml和settings.xml里面的内容,但都是大略带过,学习与研究地并不细致,本文的目的就是详细研究下这两个Maven重要的配置文件,从这两个配置文件可以牵出非常多的Maven话题.  Maven坐标 首先谈一下为什么要使用Maven坐标. Maven世界拥有数量非常巨大的构件,也就是平时使用的一些jar

  • Maven  pom.xml与settings.xml详解

    pom.xml与settings.xml pom.xml与setting.xml,可以说是Maven中最重要的两个配置文件,决定了Maven的核心功能,虽然之前的文章零零碎碎有提到过pom.xml和settings.xml里面的内容,但都是大略带过,学习与研究地并不细致,本文的目的就是详细研究下这两个Maven重要的配置文件,从这两个配置文件可以牵出非常多的Maven话题.  Maven坐标 首先谈一下为什么要使用Maven坐标. Maven世界拥有数量非常巨大的构件,也就是平时使用的一些jar

  • Maven默认中央仓库(settings.xml 配置详解)

    Maven的安装 安装Maven之前要确保已经安装好了jdk,并且配置好了环境变量JAVA_HOME.具体安装步骤如下: 1. 从apache网上下载maven项目的压缩包.下载地址为:http://maven.apache.org/download.html.比如现在最新的Maven版本是3.0.4,那么我下载好的安装文件就是apache-maven-3.0.4.zip. 2. 将下载后的压缩包解压到Maven的安装目录,比如说是D:\\develop,那么解压后就是D:\\develop\\

  • Maven 命令行打包 和 pom.xml的常用配置详解

    maven 命令行打包 mvn -v, --show-version 现在最新的maven版本是 3.6,我这里用的还是 2017 年下载的 3.1.1 版本(虽然有点过时,但是大版本不变,指令基本一样) mvn -h, --help 使用 help 命令可以看到 maven 命令的帮助文档,下面主要介绍两个常用的指令 -- D 和 P. mvn -D, --define <arg> mvn -DpropertyName=propertyValue clean package 可以用来临时定义

  • ssm框架下web项目,web.xml配置文件的作用(详解)

    1. web.xml中配置了CharacterEncodingFilter,配置这个是拦截所有的资源并设置好编号格式. encoding设置成utf-8就相当于request.setCharacterEncoding("UTF-8"); foreEncoding设置成true就相当于response.setCharacterEncoding("UTF-8"); <filter> <filter-name>CharacterEncodingFi

  • Android使用xml自定义图片实例详解

    Android使用xml自定义图片实例详解 实现效果图: 白色圆角图片 bg_round_rectangle_white.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-

  • jQ处理xml文件和xml字符串的方法(详解)

    1.xml文件 <?xml version="1.0" encoding="utf-8" ?> <root> <book id="1"> <name>锋利的jQuery1</name> <author>XXX1</author> <price>250</price> </book> <book id="2&quo

  • 对python 生成拼接xml报文的示例详解

    最近临时工作要生成xml报名,通过MQ接口发送.简单小程序. 自增长拼成xml报文 Test_001.py # encoding=utf-8 import time orderId = '' s1= "\n" # for ID in range(1,5): item1 = "<item>" + \ "<orderID>" + str(ID) + "</orderID>" + \ "

  • SpringBoot集成JmsTemplate(队列模式和主题模式)及xml和JavaConfig配置详解

    1.导入jar包: <!--jmsTemplate--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</g

  • python与xml数据的交互详解

    目录 一 什么是XML? 二 XML语法规则 1. xml语法规则 2. xml与html的区别 三 python与xml的交互 1. 获取标签对内的数据 2. 获取标签属性值 一 什么是XML? python与json数据的交互详情 在这篇文章中我们介绍了json是一种独立于编程语言和平台的数据存储和交换方式(格式),其实xml和json基本一样,也是一种用于进行数据存储和交换的方式,并且也独立于编程语言和平台.XML可扩展标记语言(英语:Extensible Markup Language,

随机推荐