关于java:Maven实战与原理分析一maven超全使用指南总结

32次阅读

共计 19944 个字符,预计需要花费 50 分钟才能阅读完成。

 

maven package 和 maven install 有什么区别?

你罕用的 maven 命令有哪些?

<dependencyManagement> 是干什么的?

还有用过其它构建工具吗? 和 maven 有啥区别?

这几个问题都能够脱口而出,你应该是有点 maven 能耐,写代码去吧,不必看了

点赞 + 珍藏 就学会系列,文章收录在 GitHub JavaEgg,N 线互联网开发必备技能兵器谱

1.Maven 是啥:

Maven 是 Apache 软件基金会惟一保护的一款 自动化构建工具 ,专一于服务 Java 平台的 我的项目构建 依赖治理

Maven 是基于我的项目对象模型(POM),能够通过一小段形容信息来治理我的项目的构建、报告和文档的软件项目管理工具。

2.Maven 能够干啥:

  • 增加第三方 jar 包
  • jar 包之间的依赖关系:Maven 能够替咱们主动的将以后 jar 包所依赖的其余所有 jar 包全副导入进来
  • 获取第三方 jar 包:Maven 提供了一个齐全对立标准的 jar 包管理体系,只须要在我的项目中以坐标的形式依赖一个 jar 包,Maven 就会主动从地方仓库进行下载到本地仓库
  • 将我的项目拆分成多个工程模块
  • 构建我的项目(打包,编译等)

3. 构建我的项目的几个次要环节:

  • 清理(clean):删除以前的编译后果,为从新编译做好筹备
  • 编译(compile):将 Java 源程序编译为字节码文件
  • 测试(test):针对我的项目中的关键点进行测试,确保我的项目在迭代开发过程中关键点的正确性
  • 报告:在每一次测试后以规范的格局记录和展现测试后果
  • 打包(package):将一个蕴含诸多文件的工程封装为一个压缩文件用于装置或部署。Java 工程对应 jar 包,Web 工程对应 war 包。
  • 装置(install):在 Maven 环境下特指将打包的后果——jar 包或 war 包装置到本地仓库中。
  • 部署(deploy):将打包的后果部署到近程仓库或将 war 包部署到服务器上运行。

4.Maven 常用命令

  • mvn -version/-v —— 显示版本信息
  • mvn clean —— 清空生成的文件
  • mvn compile —— 编译
  • mvn test —— 编译并测试
  • mvn package —— 生成 target 目录,编译、测试代码,生成测试报告,生成 jar/war 文件
  • mvn site —— 生成我的项目相干信息的网站
  • mvn clean compile —— 示意先运行清理之后运行编译,会将代码编译到 target 文件夹中
  • mvn clean package —— 运行清理和打包
  • mvn clean install —— 运行清理和装置,会将打好的包装置到本地仓库中,以便其余的我的项目能够调用
  • mvn clean deploy —— 运行清理和公布

5.Maven 外围概念

Maven 可能实现自动化构建是和它的外部原理分不开的,这里咱们从 Maven 的九个外围概念动手,看看 Maven 是如何实现自动化构建的

  • POM
  • 约定的目录构造
  • 坐标
  • 依赖治理
  • 仓库治理
  • 生命周期
  • 插件和指标
  • 继承
  • 聚合

Maven 的外围程序中仅仅定义了形象的生命周期,而具体的操作则是由 Maven 的插件来实现的。可是 Maven 的插件并不蕴含在 Maven 的外围程序中,在首次应用时须要联网下载。下载失去的插件会被保留到本地仓库中。本地仓库默认的地位是:~.m2\repository。

5.1. Maven 约定的工程目录:

Java 开发畛域广泛认同的一个观点:约定 > 配置 > 编码(能用配置解决的问题就不编码,能基于约定的就不配置)

5.2. POM

Project Object Model:我的项目对象模型。将 Java 工程的相干信息封装为对象作为便于操作和治理的模型。

Maven 工程的外围配置。

5.3. 坐标

  • Maven 的坐标 应用如下三个向量在 Maven 的仓库中惟一的确定一个 Maven 工程。
    • groupid:公司或组织的域名倒序 + 以后项目名称
    • artifactId:以后我的项目的模块名称
    • version:以后模块的版本
  <groupId>net.lazyegg.maven</groupId>
  Hello
  <version>0.0.1-SNAPSHOT</version>
复制代码

  • 如何通过坐标到仓库中查找 jar 包?

    • 将 gav 三个向量连起来


```
net.lazyegg.maven+Hello+0.0.1-SNAPSHOT
复制代码
```

![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== "点击并拖拽以挪动")

*   以连起来的字符串作为目录构造到仓库中查找

    net/lazyegg/maven/Hello/0.0.1-SNAPSHOT/Hello-0.0.1-SNAPSHOT.jar

※ 留神:咱们本人的 Maven 工程必须执行安装操作才会进入仓库。装置的命令是:mvn install

5.4. 依赖

Maven 中最要害的局部,咱们应用 Maven 最次要的就是应用它的依赖治理性能。要了解和把握 Maven 的依赖治理,咱们只须要解决以下几个问题:

① 依赖的目标是什么

当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,这是概念上的形容。那么如何在我的项目中以依赖的形式引入一个咱们须要的 jar 包呢?答案非常简单,就是应用 dependency 标签指定被依赖 jar 包的坐标就能够了。

<dependency>
    <groupId>net.lazyegg.maven</groupId>
    Hello
    <version>0.0.1-SNAPSHOT</version>
    <scope>compile</scope>            
</dependency>
复制代码

② 依赖的范畴

有时依赖信息中除了指标 jar 包的坐标还有一个 scope 设置,这就是依赖的范畴。依赖的范畴有几个可选值,罕用的有:compile、test、provided 三个,当然还有不罕用的 runtime、system..

  • compile默认范畴,编译测试运行都无效
  • provided:在编译和测试时无效
  • runtime:在测试和运行时无效
  • test:只在测试时无效
  • system:在编译和测试时无效,与本机系统关联,可移植性差
  • 罕用依赖范畴有效性总结
compile test provided
主程序 ×
测试程序
参加部署 × ×

③ 依赖的传递性

A 依赖 B,B 依赖 C,A 是否应用 C 呢?那要看 B 依赖 C 的范畴是不是 compile,如果是则可用,否则不可用。

④ 依赖的排除

如果咱们在以后工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会主动将 A 依赖的 B 引入当 前工程,然而个别情况下 B 有可能是一个不稳定版,或对以后工程有不良影响。这时咱们能够在引入 A 的时候将 B 排除。

<dependency>
    <groupId>net.lazyegg.maven</groupId>
    Hello
    <version>0.0.1-SNAPSHOT</version>
    <scope>compile</scope>
    <exclusions>
    <exclusion>
    <groupId>commons-logging</groupId>
    commons-logging
    </exclusion>
    </exclusions>
</dependency>
复制代码

⑤ 对立管理所依赖 jar 包的版本,对同一个框架的一组 jar 包最好应用雷同的版本。为了不便降级框架,能够将 jar 包的版本信息对立提取进去

  • 对立申明版本号
<properties>
    <starfish.spring.version>4.1.1.RELEASE</starfish.spring.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
复制代码

  • 援用后面申明的版本号
<dependency>
    <groupId>org.springframework</groupId>
    spring-core
    <version>${starfish.spring.version}</version>
    <scope>compile</scope>
</dependency>
复制代码

⑥ 依赖的准则:解决 jar 包抵触

  • 门路最短者优先
  • 门路雷同时先声明者优先

我的项目版本抵触时候的那种蛋疼的感觉,只有疼过的才晓得,所以,咱们来看看疼过的人是怎么解决的,举荐一个 IDEA 插件,Maven Helper,比自带的好用,高深莫测

5.5. 仓库

  • 分类

    • 本地仓库:为以后本机电脑上的所有 Maven 工程服务
    • 近程仓库

      • 私服:架设在以后局域网环境下,为以后局域网范畴内的所有 Maven 工程服务
      • 地方仓库:架设在 Internet 上,为全世界所有 Maven 工程服务
      • 地方仓库的镜像:架设在各个大洲,为地方仓库分担流量。加重地方仓库的压力,同时更快的响应用户申请,比方阿里的镜像
  • 仓库中的文件

    • Maven 的插件
    • 咱们本人开发的我的项目的模块
    • 第三方框架或工具的 jar 包 ※ 不论是什么样的 jar 包,在仓库中都是依照坐标生成目录构造,所以能够通过对立的形式查问或依赖,查问地址:mvnrepository.com/

5.6. 生命周期

5.6.1. 什么是 Maven 的生命周期?

Maven 生命周期定义了各个构建环节的执行程序,有了这个清单,Maven 就能够自动化的执行构建命令了。

Maven 有三套互相独立的生命周期,别离是:

  • Clean Lifecycle 在进行真正的构建之前进行一些清理工作
  • Default Lifecycle 构建的外围局部,编译,测试,打包,装置,部署等等
  • Site Lifecycle 生成我的项目报告,站点,公布站点

它们是互相独立的,你能够仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。当然你也能够间接运行 mvn clean install site 运行所有这三套生命周期。每套生命周期都由一组阶段 (Phase) 组成,咱们平时在命令行输出的命令总会对应于一个特定的阶段。比 如,运行 mvn clean,这个 clean 是 Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段。

5.6.2. Clean 生命周期

Clean 生命周期一共蕴含了三个阶段:

  • pre-clean 执行一些须要在 clean 之前实现的工作
  • clean 移除所有上一次构建生成的文件
  • post-clean 执行一些须要在 clean 之后立即实现的工作

5.6.3. Site 生命周期

  • pre-site 执行一些须要在生成站点文档之前实现的工作
  • site 生成我的项目的站点文档
  • post-site 执行一些须要在生成站点文档之后实现的工作,并且为部署做筹备
  • site-deploy 将生成的站点文档部署到特定的服务器上 这里常常用到的是 site 阶段和 site-deploy 阶段,用以生成和公布 Maven 站点,这可是 Maven 相当弱小 的性能,Manager 比拟喜爱,文档及统计数据主动生成,很难看。

5.6.4. Default 生命周期

Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都产生在这个生命周期中(列出一些重要阶段)

  • validate:验证工程是否正确,所有须要的资源是否可用。
  • compile:编译我的项目的源代码。
  • test:应用适合的单元测试框架来测试已编译的源代码。这些测试不须要已打包和布署。
  • package:把已编译的代码打包成可公布的格局,比方 jar、war 等。
  • integration-test:如有须要,将包解决和公布到一个可能进行集成测试的环境。
  • verify:运行所有查看,验证包是否无效且达到质量标准。
  • install:把包装置到 maven 本地仓库,能够被其余工程作为依赖来应用。
  • deploy:在集成或者公布环境下执行,将最终版本的包拷贝到近程的 repository,使得其余的开发者或者工程能够共享

5.6.5. 生命周期与自动化构建

运行任何一个阶段的时候,它后面的所有阶段都会被运行,例如咱们运行 mvn install 的时候,代码会被编译,测试,打包。这就是 Maven 为什么可能主动执行构建过程的各个环节的起因。此外,Maven 的插件机制是齐全依赖 Maven 的生命周期的,因而了解生命周期至关重要。

5.7. 插件和指标

  • Maven 的外围仅仅定义了形象的生命周期,具体的工作都是交由插件实现的
  • 每个插件都能实现多个性能,每个性能就是一个插件指标
  • Maven 的生命周期与插件指标互相绑定,以实现某个具体的构建工作 例如:compile 就是插件 maven-compiler-plugin 的一个指标;pre-clean 是插件 maven-clean-plugin 的一个指标

5.8. 继承

  • 为什么须要继承机制?因为非 compile 范畴的依赖信息是不能在“依赖链”中传递的,所以有须要的工程只能独自配置
  • 创立父工程 创立父工程和创立个别的 Java 工程操作统一,惟一须要留神的是:打包形式处要设置为 pom
  • 在子工程中援用父工程,从当前目录到父我的项目的 pom.xml 文件的相对路径
 <parent>
     <groupId>com.starfish.maven</groupId>
    Parent
    <version>0.0.1-SNAPSHOT</version>
    <!-- 以以后文件为基准的父工程 pom.xml 文件的相对路径 -->
    <relativePath>../Parent/pom.xml</relativePath>
</parent>
复制代码

此时如果子工程的 groupId 和 version 如果和父工程反复则能够删除。

  • 在父工程中治理依赖 将 Parent 我的项目中的 dependencies 标签,用 dependencyManagement 标签括起来
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            junit
            <version>4.9</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</dependencyManagement> 
复制代码

在子项目中从新指定须要的依赖,删除范畴和版本号

<dependency>
    <groupId>junit</groupId>
    junit
</dependency>
复制代码

5.9. 聚合

  • 为什么要应用聚合?

将多个工程拆分为模块后,须要手动一一装置到仓库后依赖才可能失效。批改源码后也须要一一手动进 行 clean 操作。而应用了聚合之后就能够批量进行 Maven 工程的装置、清理工作。

如何配置聚合?在总的聚合工程中应用 modules/module 标签组合,指定模块工程的相对路径即可

本来地址:Maven 入门,读完这篇就够了

博客地址:tengj.top/

前言

夜空中最亮的星,2018 请照亮我前行~ Maven 是咱们日常开发都会用到的,新年第一天,把看过的 Maven 根底概念做了整顿,作为入门和查阅应用。

注释

Maven 概念

Maven 作为一个构建工具,不仅能帮咱们自动化构建,还可能形象构建过程,提供构建工作实现; 它跨平台,对外提供了统一的操作接口,这所有足以使它成为优良的、风行的构建工具。

Maven 不仅是构建工具,还是一个依赖管理工具和项目管理工具,它提供了地方仓库,能帮我主动下载构件。

maven 的装置

一:因为自己是 window 零碎,所以这里只介绍 window 下如何装置,在装置 Maven 之前,先确认曾经装置了 JDK.

二:接着去 Maven 官网下载界面下载想要的版本解压到你想要的目录就行

三:最初设置一下环境变量,将 Maven 装置配置到操作系统环境中,次要就是配置 M2_HOME PATH两项,如图

都搞定后,验证一下,关上 doc 输出 mvn - v 如何失去上面信息就阐明配置胜利了

maven 目录

  • bin 目录

该目录蕴含了 mvn 运行的脚本,这些脚本用来配置 java 命令,筹备好 classpath 和相干的 Java 零碎属性,而后执行 Java 命令。

  • boot 目录

该目录只蕴含一个文件,该文件为 plexus-classworlds-2.5.2.jar。plexus-classworlds 是一个类加载器框架,绝对于默认的 java 类加载器,它提供了更加丰盛的语法以不便配置,Maven 应用该框架加载本人的类库。

  • conf 目录:

该目录蕴含了一个十分重要的文件 settings.xml。间接批改该文件,就能在机器上全局地定制 Maven 的行为,个别状况下,咱们更偏差于复制该文件至~/.m2/ 目录下(~ 示意用户目录),而后批改该文件,在用户范畴定制 Maven 的行为。

  • lib 目录:

该目录蕴含了所有 Maven 运行时须要的 Java 类库,Maven 自身是分模块开发的,因而用户能看到诸如 maven-core-3.0.jar、maven-model-3.0.jar 之类的文件,此外这里还蕴含一些 Maven 用到的第三方依赖如 commons-cli-1.2.jar、commons-lang-2.6.jar 等等。

Maven 常用命令阐明

  • mvn clean:示意运行清理操作(会默认把 target 文件夹中的数据清理)。
  • mvn clean compile:示意先运行清理之后运行编译,会将代码编译到 target 文件夹中。
  • mvn clean test:运行清理和测试。
  • mvn clean package:运行清理和打包。
  • mvn clean install:运行清理和装置,会将打好的包装置到本地仓库中,以便其余的我的项目能够调用。
  • mvn clean deploy:运行清理和公布(公布到私服下面)。

下面的命令大部分都是连写的,大家也能够拆分别离执行,这是活的,看集体爱好以及应用需要,Eclipse Run as 对 maven 我的项目会提供罕用的命令。

设置 http 代理

编辑 seeting.xml 文件 有时候你所在的公司基于平安因素思考,要求你应用通过平安认证的代理拜访因特网。这种状况下,就须要为 Maven 配置 HTTP 代理,能力让它失常拜访内部仓库,以下载所须要的资源。首先确认本人无奈间接拜访公共的 maven 地方仓库,间接运行命令 ping repo1.maven.org 能够查看网络。如果真的须要代理,先检查一下代理服务器是否畅通。比方当初有一个 IP 地址为 218.14.227.197,端口为 3128 的代理服务,咱们能够运行 telnet 218.14.227.197 3128 来检测该地址的该端口是否畅通。如果失去出错信息,须要先获取正确的代理服务信息,如果 telnet 连贯正确,则输出 ctrl+],而后 q,回车,退出即可。

查看结束之后,编辑~/.m2/settings.xml 文件(如果没有该文件,则复制 $M2_HOME/conf/settings.xml)。增加代理配置如下:

<settings>  
  ...  
  <proxies>  
    <proxy>  
      <id>my-proxy</id>  
      true  
      <protocol>http</protocol>  
      <host>218.14.227.197</host>  
      <port>3128</port>  
      <!--  
        <username>***</username>  
        <password>***</password>  
        <nonProxyHosts>  
          repository.mycom.com|*.google.com  
        </nonProxyHosts>  
      -->  
    </proxy>  
  </proxies>  
  ...  
</settings> 
复制代码

这段配置非常简略,proxies 下能够有多个 proxy 元素,如果申明了多个 proxy 元素,则默认状况下第一个被激活的 proxy 会失效。这里申明了一个 id 为 my-proxy 的代理,active 的值为 true 示意激活该代理,protocol 示意应用的代理协定,这里是 http。当然,最重要的是指定正确的主机名 (host 元素) 和端口(port 元素)。上述 xml 配置中正文掉了 username,password,nonProxyHosts 几个元素。当代理服务须要认证时,就须要配置 username 和 password。nonProxyHost 元素用来指定哪些主机不须要代理,能够应用 ”|” 符号来分隔多个主机名。此外,该配置也反对通配符,如:*.google.com 示意所有以 google.com 结尾的域名拜访都不要通过代理。

Maven 插件装置,基于 IDEA

博主当初应用 IDEA 来开发的,所以这里介绍一下 IDEA 中如何配置引入咱们下面下载好的 Maven

Maven 应用

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.tengj</groupId>
    springBootDemo1
    <version>0.0.1-SNAPSHOT</version>
    <name>springBootDemo1</name>
</project>
复制代码

代码的第一行是 XML 头,指定了该 xml 文档的版本和编码方式。project 是所有 pom.xml 的根元素,它还申明了一些 POM 相干的命名空间及 xsd 元素。根元素下的第一个子元素 modelVersion 指定了以后的 POM 模型的版本,对于 Maven3 来说,它只能是 4.0.0 代码中最重要是蕴含了 groupId,artifactId 和 version 了。这三个元素定义了一个我的项目根本的坐标,在 Maven 的世界,任何的 jar、pom 或者 jar 都是以基于这些根本的坐标进行辨别的。

groupId 定义了我的项目属于哪个组,随便命名,比方谷歌公司的 myapp 我的项目,就取名为 com.google.myapp

artifactId 定义了以后 Maven 我的项目在组中惟一的 ID, 比方定义 hello-world。

version 指定了我的项目以后的版本 0.0.1-SNAPSHOT,SNAPSHOT 意为快照,阐明该我的项目还处于开发中,是不稳固的。

name 元素生命了一个对于用户更为敌对的项目名称,尽管这不是必须的,但还是举荐为每个 POM 申明 name, 以不便信息交换

依赖的配置

<project>
...
<dependencies>
    <dependency>
        <groupId> 理论我的项目 </groupId>
     模块
     <version> 版本 </version>
     <type> 依赖类型 </type>
     <scope> 依赖范畴 </scope>
     <optional> 依赖是否可选 </optional>
     <!—次要用于排除传递性依赖 -->
     <exclusions>
         <exclusion>
           <groupId>…</groupId>
          …
       </exclusion>
     </exclusions>
  </dependency>
<dependencies>
...
</project>
复制代码

根元素 project 下的 dependencies 能够蕴含一个或者多个 dependency 元素,以申明一个或者多个我的项目依赖。每个依赖能够蕴含的元素有:

  • grounpId、artifactId 和 version: 以来的根本坐标,对于任何一个依赖来说,根本坐标是最重要的,Maven 依据坐标能力找到须要的依赖。
  • type: 依赖的类型,对于我的项目坐标定义的 packaging。大部分状况下,该元素不用申明,其默认值为 jar
  • scope: 依赖的范畴
  • optional: 标记依赖是否可选
  • exclusions: 用来排除传递性依赖

依赖范畴

依赖范畴就是用来管制依赖和三种 classpath(编译 classpath,测试 classpath、运行 classpath)的关系,Maven 有如下几种依赖范畴:

  • compile:编译依赖范畴。如果没有指定,就会默认应用该依赖范畴。应用此依赖范畴的 Maven 依赖,对于编译、测试、运行三种 classpath 都无效。典型的例子是 spring-code, 在编译、测试和运行的时候都须要应用该依赖。
  • test: 测试依赖范畴。应用次依赖范畴的 Maven 依赖,只对于测试 classpath 无效,在编译主代码或者运行我的项目的应用时将无奈应用此依赖。典型的例子是 Jnuit, 它只有在编译测试代码及运行测试的时候才须要。
  • provided:已提供依赖范畴。应用此依赖范畴的 Maven 依赖,对于编译和测试 classpath 无效,但在运行时候有效。典型的例子是 servlet-api, 编译和测试项目的时候须要该依赖,但在运行我的项目的时候,因为容器以及提供,就不须要 Maven 反复地引入一遍。
  • runtime:运行时依赖范畴。应用此依赖范畴的 Maven 依赖,对于测试和运行 classpath 无效,但在编译主代码时有效。典型的例子是 JDBC 驱动实现,我的项目主代码的编译只须要 JDK 提供的 JDBC 接口,只有在执行测试或者运行我的项目的时候才须要实现上述接口的具体 JDBC 驱动。
  • system:零碎依赖范畴。该依赖与三种 classpath 的关系,和 provided 依赖范畴完全一致,然而,应用 system 范畴的依赖时必须通过 systemPath 元素显示地指定依赖文件的门路。因为此类依赖不是通过 Maven 仓库解析的,而且往往与本机系统绑定,可能形成构建的不可移植,因而应该审慎应用。systemPath 元素能够援用环境变量,如:
<dependency>
    <groupId>javax.sql</groupId>
    jdbc-stdext
    <Version>2.0</Version>
    <scope>system</scope>
    <systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
复制代码

  • import:导入依赖范畴。该依赖范畴不会对三种 classpath 产生理论的影响。

上述除 import 以外的各种依赖范畴与三种 classpath 的关系如下:

传递性依赖

比方一个 account-email 我的项目为例,account-email 有一个 compile 范畴的 spring-code 依赖,spring-code 有一个 compile 范畴的 commons-logging 依赖,那么 commons-logging 就会成为 account-email 的 compile 的范畴依赖,commons-logging 是 account-email 的一个传递性依赖

有了传递性依赖机制,在应用 Spring Framework 的时候就不必去思考它依赖了什么,也不必放心引入多余的依赖。Maven 会解析各个间接依赖的 POM,将那些必要的间接依赖,以传递性依赖的模式引入到以后的我的项目中。

依赖范畴

假如 A 依赖于 B,B 依赖于 C,咱们说 A 对于 B 是第一间接依赖,B 对于 C 是第二间接依赖,A 对于 C 是传递性依赖。第一间接依赖和第二间接依赖的范畴决定了传递性依赖的范畴,如下图所示,最右边一行示意第一间接依赖范畴,最下面一行示意第二间接依赖范畴,两头的穿插单元格则示意传递依赖范畴。

从上图中,咱们能够发现这样的法则:

  • 当第二间接依赖的范畴是 compile 的时候,传递性依赖的范畴与第一间接依赖的范畴统一;
  • 当第二间接依赖的范畴是 test 的时候,依赖不会得以传递;
  • 当第二间接依赖的范畴是 provided 的时候,只传递第一间接依赖范畴也为 provided 的依赖,切传递依赖的范畴同样为 provided;
  • 当第二间接依赖的范畴是 runtime 的时候,传递性依赖的范畴与第一间接依赖的范畴统一,但 compile 列外,此时传递性依赖范畴为 runtime.

 依赖调解 有时候,当传递性依赖造成为题的时候,就须要分明地晓得该传递性依赖是从哪条依赖门路引入的。这就是依赖调解的作用,依赖调解有两大准则:1. 门路最近者优先 比方我的项目有 A 有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0),X 是 A 的传递性依赖,然而两条依赖门路上有两个版本的 X,所以依据第一准则,A->D->X(2.0)门路短,所以 X(2.0)会被解析应用 2. 第一声明者优先 如果门路都一样长的话,第一准则就不行了,比方 A->B->Y(1.0)、A->C->Y(2.0),Y(1.0)和 Y(2.0)的门路一样,所以这时候依据第二准则,先申明的被解析。

 可选依赖

如图,我的项目中 A 依赖 B,B 依赖于 X 和 Y,如果所有这三个的范畴都是 compile 的话,那么 X 和 Y 就是 A 的 compile 范畴的传递性依赖,然而如果我想 X,Y 不作为 A 的传递性依赖,不给他用的话。就须要上面提到的配置可选依赖。

<project>  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.juvenxu.mvnbook</groupId>  
    project-b  
    <version>1.0.0</version>  
    <dependencies>  
        <dependency>  
            <groupId>mysql</groupId>  
            mysql-connector-java  
            <version>5.1.10</version>  
            <optional>true</optional>  
        </dependency>  
        <dependency>  
            <groupId>postgresql</groupId>  
            postgresql</groupId>  
            <version>8.4-701.jdbc3</version>  
            <optional>true</optional>  
        </dependency>  
    </dependencies>  
</project>  
复制代码

配置也简略,在依赖外面增加

<optional>true</optional>
复制代码

就示意可选依赖了,这样 A 如果想用 X,Y 就要间接显示的增加依赖了。

排除依赖

有时候你引入的依赖中蕴含你不想要的依赖包,你想引入本人想要的,这时候就要用到排除依赖了,比方下图中 spring-boot-starter-web 自带了 logback 这个日志包,我想引入 log4j2 的,所以我先排除掉 logback 的依赖包,再引入想要的包就行了

排除依赖代码构造:

<exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-logging
    </exclusion>
</exclusions>
复制代码

这里留神:申明 exclustion 的时候只须要 groupId 和 artifactId,而不须要 version 元素,这是因为只须要 groupId 和 artifactId 就能惟一定位依赖图中的某个依赖。

归类依赖

有时候咱们引入的很多依赖包,他们都来自同一个我的项目的不同模块,所以他们的版本号都一样,这时候咱们能够用属性来对立治理版本号

<project>  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>com.juven.mvnbook.account</groupId>  
    accout-email  
    <version>1.0.0-SNAPSHOT</version>  
    <properties>  
        <springframework.version>1.5.6</springframework.version>  
    </properties>  
    <dependencies>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            spring-core  
            <version>${springframework.version}</version>  
        </dependency>   
        <dependency>  
            <groupId>org.springframework</groupId>  
            spring-beans  
            <version>${springframework.version}</version>  
        </dependency>         
    </dependencies>  
</project>  
复制代码

如图所示,先通过

</properties>
    这里定义你先要的版本
</properties>
复制代码

来定义,而后在上面依赖应用 ${}来引入你的属性。

仓库

这节将介绍仓库的由来、布局、分类、配置、外部工作机制、镜像等概念

仓库的由来

在 Maven 世界中,任何一个依赖、插件或者我的项目构建的输入,都能够称为构件。得益于坐标机制,任何 Maven 我的项目应用任何一个构件的形式都是完全相同的。在此基础上,Maven 能够在某个地位对立存储所有 Maven 我的项目共享的构件,这个对立的地位就是仓库。

理论的 Maven 我的项目将不再各自存储其依赖文件,它们只须要申明这些依赖的坐标,在须要的时候(例如,编译我的项目的时候须要将依赖退出到 classpath 中),Maven 会主动依据坐标找到仓库中的构件,并应用它们。

为了实现重用,我的项目构建结束后可生成的构件也能够装置或者部署到仓库中,供其余我的项目应用。

仓库的布局

任何一个构件都有其惟一的坐标,依据这个坐标能够定义其在仓库中的惟一存储门路,这便是 Maven 的仓库布局形式。该路经与坐标对应关系为 groupId/artifactId/version/artifactId-version.packaging。举个例子,比方上面这个分页插件依赖如下:

<dependency>
      <groupId>com.github.pagehelper</groupId>
      pagehelper-spring-boot-starter
      <version>1.1.0</version>
</dependency>
复制代码

那他对应的仓库的门路就是这样:

Maven 仓库是基于简略文件系统存储的,咱们也了解其存储形式、因而,当遇到一些与仓库相干的问题时,能够很不便的查找相干文件,不便定位问题。

仓库的分类

本地仓库

一般来说,在 Maven 我的项目目录下,没有诸如 lib/ 这样用来寄存依赖文件的目录。当 Maven 在执行编译或测试时,如果须要应用依赖文件,它总是基于坐标应用本地仓库的依赖文件。

默认状况下,不论在 Window 还是 Linux 下,每个用户在本人用户目录下都有一个路径名为.m2/repository/ 的仓库目录。如果你想自定义本地仓库目录地址。你能够编辑文件~/.m2/settings.xml,设置 localRepository 元素的值为想要的仓库地址,例如:

<settings>
<localRepository>D:\java\repository\</localRepository>
</settings>
复制代码

这样,该用户的本地仓库地址就被设置成了 D:\java\repository\。须要留神的是,默认状况下,~/.m2/settings.xml 文件不存在,用户须要从 Maven 装置目录复制 $M2_HOME/conf/settings.xml 文件再进行编辑。

近程仓库 - 地方仓库

因为最原始的本地仓库是空的,Maven 必须晓得至多一个可用的近程仓库,能力在执行 Maven 命令的时候下载到须要的构件。地方仓库就是这样一个默认的近程仓库,Maven 的安装文件自带了地方仓库的配置。

地方仓库蕴含了这个世界上绝大多数风行的开源 Java 构件,以及源码、作者信息、SCM, 信息、许可证信息等,每个月这里都会承受全世界 Java 程序员大略 1 亿次的拜访,它对全世界 Java 开发者的奉献由此可见一斑。

近程仓库 - 私服

私服是一种非凡的近程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的近程仓库,供局域网内的 Maven 用户应用。当 Maven 须要下载构件的时候,它从私服申请,如果私服上不存在该构件,则从内部的近程仓库下载,缓存在私服上之后,再为 Maven 的下载申请提供服务。因而,一些无奈从内部仓库下载到的构件也能从本地上传到私服上供大家应用。私服的益处:

  • 节俭本人的外网速度
  • 减速 Maven 构建
  • 部署第三方构建
  • 进步稳定性,加强管制
  • 升高地方仓库的负荷

近程仓库的配置

在平时的开发中,咱们往往不会应用默认的地方仓库,默认的地方仓库拜访的速度比较慢,拜访的人或者很多,有时候也无奈满足咱们我的项目的需要,可能我的项目须要的某些构件地方仓库中是没有的,而在其余近程仓库中有,如 JBoss Maven 仓库。这时,能够在 pom.xml 中配置该仓库,代码如下:

<!-- 配置近程仓库 -->
    <repositories>
        <repository>
            <id>jboss</id>
            <name>JBoss Repository</name>
            <url>http://repository.jboss.com/maven2/</url>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
            </releases>
            <snapshots>
                <enabled>false</enabled>
                <checksumPolicy>warn</checksumPolicy>
            </snapshots>
            <layout>default</layout>
        </repository>
    </repositories>
复制代码

  • repository:在 repositories 元素下,能够应用 repository 子元素申明一个或者多个近程仓库。
  • id:仓库申明的惟一 id,尤其须要留神的是,Maven 自带的地方仓库应用的 id 为 central,如果其余仓库申明也应用该 id,就会笼罩地方仓库的配置。
  • name:仓库的名称,让咱们直观不便的晓得仓库是哪个,临时没发现其余太大的含意。
  • url:指向了仓库的地址,一般来说,该地址都基于 http 协定,Maven 用户都能够在浏览器中关上仓库地址浏览构件。
  • releases 和 snapshots:用来管制 Maven 对于公布版构件和快照版构件的下载权限。须要留神的是 enabled 子元素,该例中 releases 的 enabled 值为 true,示意开启 JBoss 仓库的公布版本下载反对,而 snapshots 的 enabled 值为 false,示意敞开 JBoss 仓库的快照版本的下载反对。依据该配置,Maven 只会从 JBoss 仓库下载公布版的构件,而不会下载快照版的构件。
  • layout:元素值 default 示意仓库的布局是 Maven2 及 Maven3 的默认布局,而不是 Maven1 的布局。根本不会用到 Maven1 的布局。
  • 其余:对于 releases 和 snapshots 来说,除了 enabled,它们还蕴含另外两个子元素 updatePolicy 和 checksumPolicy。

1:元素 updatePolicy 用来配置 Maven 从远处仓库查看更新的频率,默认值是 daily,示意 Maven 每天查看一次。其余可用的值包含:never- 从不查看更新;always- 每次构建都查看更新;interval:X- 每隔 X 分钟查看一次更新(X 为任意整数)。
2:元素 checksumPolicy 用来配置 Maven 查看校验和文件的策略。当构建被部署到 Maven 仓库中时,会同时部署对应的测验和文件。在下载构件的时候,Maven 会验证校验和文件,如果校验和验证失败,当 checksumPolicy 的值为默认的 warn 时,Maven 会在执行构建时输入正告信息,其余可用的值包含:fail-Maven 遇到校验和谬误就让构建失败;ignore- 使 Maven 齐全疏忽校验和谬误。

近程仓库的认证

大部分的近程仓库不须要认证,然而如果是本人外部应用,为了平安起见,还是要配置认证信息的。配置认证信息和配置近程仓库不同,近程仓库能够间接在 pom.xml 中配置,然而认证信息必须配置在 settings.xml 文件中。这是因为 pom 往往是被提交到代码仓库中供所有成员拜访的,而 settings.xml 个别只存在于本机。因而,在 settings.xml 中配置认证信息更为平安。

<settings>
 2     ...
 3     <!-- 配置近程仓库认证信息 -->
 4     <servers>
 5         <server>
 6             <id>releases</id>
 7             <username>admin</username>
 8             <password>admin123</password>
 9         </server>
10     </servers>
11     ...
12 </settings>
复制代码

这里除了配置账号密码之外,值要害的就是 id 了,这个 id 要跟你在 pom.xml 外面配置的近程仓库 repository 的 id 统一,正是这个 id 将认证信息与仓库配置分割在了一起。

部署构件至近程仓库

咱们本人搭建近程仓库的目标就是为了能够不便部署咱们本人我的项目的构件以及一些无奈从内部仓库间接获取的构件。这样能力在开发时,供其余对团队成员应用。Maven 除了能对我的项目进行编译、测试、打包之外,还能将我的项目生成的构件部署到近程仓库中。首先,须要编辑我的项目的 pom.xml 文件。配置 distributionManagement 元素,代码如下:

<distributionManagement>
        <repository>
            <id>releases</id>
            <name>public</name>
            <url>http://59.50.95.66:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <name>Snapshots</name>
            <url>http://59.50.95.66:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
</distributionManagement>
复制代码

看代码,从命名上就看的进去区别,repository 示意示意公布版本(稳固版本)构件的仓库,snapshotRepository 示意快照版本(开发测试版本)的仓库。这两个元素都须要配置 id、name 和 url,id 为近程仓库的惟一标识,name 是为了不便人浏览,要害的 url 示意该仓库的地址。

配置好了就运行命令 mvn clean deploy,Maven 就会将我的项目构建输入的构件部署到配置对应的近程仓库,如果我的项目以后的版本是快照版本,则部署到快照版本的仓库地址,否则就部署到公布版本的仓库地址。以后我的项目是快照还是公布版本是通过 true 这个来辨别的。遗记的同学在看看下面的 ## 近程仓库的配置。

镜像

如果仓库 X 能够提供仓库 Y 存储的所有内容,那么就能够认为 X 是 Y 的一个镜像。用过 Maven 的都晓得,国外的地方仓库用起来太慢了,所以抉择一个国内的镜像就很有必要,我举荐国内的阿里云镜像。阿里云镜像:配置很简略,批改 conf 文件夹下的 settings.xml 文件,增加如下镜像配置:

<mirrors>
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>
  </mirrors>
复制代码

上例子中,的值为 central, 示意该配置为地方库的镜像,任何对于地方仓库的申请都会转至该镜像,用户也能够用同样的办法配置其余仓库的镜像

这里介绍下 <mirrorOf> 配置的各种选项

  • <mirrorOf>*<mirrorOf>: 匹配所有近程仓库。
  • <mirrorOf>external:*<mirrorOf>: 匹配所有近程仓库,应用 localhost 的除外,应用 file:// 协定的除外。也就是说,匹配所有不在本机上的近程仓库。
  • <mirrorOf>repo1,repo2<mirrorOf>: 匹配仓库 repo1h 和 repo2,应用逗号分隔多个近程仓库。
  • <mirrorOf>*,!repo1<mirrorOf>: 匹配所有近程仓库,repo1 除外,应用感叹号将仓库从匹配中排除。

须要留神的是,因为镜像仓库齐全屏蔽了被镜像仓库,当镜像仓库不稳固或者进行服务的时候,Maven 仍将无法访问被镜像仓库,因此将无奈下载构件。

仓库服务搜寻

这里介绍 2 个提供仓库服务搜寻的地址:

  • Sonatype Nexus:repository.sonatype.org/
  • MVNrepository:mvnrepository.com/

总结

临时先这样,前面持续补充更新本篇,对于私服搭建的会另外开一片介绍。本篇基于《Maven 实战》整顿提炼。须要电子书小伙伴可关注博主微信公众号:嘟爷 java 超神学堂(java2Learn)回复关键字 maven获取电子书。

作者:嘟嘟 MD
链接:https://juejin.cn/post/684490…
起源:稀土掘金
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

<!-- 配置聚合 -->
<modules>
    <!-- 指定各个子工程的相对路径 -->
    <module>starfish-learn-grpc</module>
    <module>starfish-learn-kafka</module>
    <module>starfish-web-demo</module>
</modules>


微信公众号【程序员黄小斜】作者是前蚂蚁金服 Java 工程师,专一分享 Java 技术干货和求职成长心得,不限于 BAT 面试,算法、计算机根底、数据库、分布式、spring 全家桶、微服务、高并发、JVM、Docker 容器,ELK、大数据等。关注后回复【book】支付精选 20 本 Java 面试必备精品电子书。

正文完
 0