Maven 依赖、插件、仓库、坐标、聚合、继承

1. 能做什么

构建、依赖管理、项目信息管理

2. 坐标

坐标是依赖管理的基础,通过坐标定位依赖的构件

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibai.test</groupId>
    <artifactId>test-maven</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>Learning more about maven</name>
  • modelVersion:当前POM模型的版本,对于Maven2和Maven3来说,只能是 4.0.0
  • groupId: 当前项目隶属的实际项目,一般命名为com.公司名.项目名
  • artifactId:实际项目中的模块,一般命名为项目名-模块名
  • version:版本,一般分为快照版本和稳定版本
  • packaging:Maven的打包方式,默认是jar
3. 依赖
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>4.1.0</version>
            <type>jar</type>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
            <scope>compile</scope>
            <optional>false</optional>
        </dependency>
  • scope


    image.png
image.png
  • 传递性依赖

    image.png

    规律:
    <1> 当第二直接依赖是 compile时,传递依赖的范围与第一直接依赖的范围一致
    <2> 当第二直接依赖是 test 时,不会有传递依赖
    <3> 当第二直接依赖是 runtime 时,传递依赖的范围与第一直接依赖范围一致,除了 compile
    <4> 当第二直接依赖是provided 时,只有第一直接依赖范围是 provided 时,传递依赖范围是 provided ,其他情况没有传递依赖。

  • 依赖调解
    比如有以下的传递性依赖

A->B->C->X(1.0)
A->D->X(2.0)

这时会使用第一个原则:路径最短原则
如果路径相同,则会使用第二个原则:声明顺序优先原则

  • optional
    可选依赖不能传递,一般情况下不建议使用可选依赖


    image.png
  • exclusions
    不想使用传递性依赖,可能版本不稳定或其他原因,将传递性依赖排除后定义为直接依赖


    image.png
  • 归类依赖
    将依赖的相同项目的不同模块的版本属性化


    image.png
  • 优化依赖
    对于项目中直接使用的包,最好定义为直接依赖,便于控制

mvn dependency:list
mvn dependency:tree
mvn dependency:analyze
4. 仓库

统一存储所有Maven项目共享的构件叫仓库

  • 仓库的布局
    坐标与构件在仓库的路径转化关系是:
groupId/artifactId/version/artifactId-version.packaging
  • 仓库分类


    image.png
  • 私服


    image.png
  • 从仓库解析依赖的机制


    image.png
  • 镜像
    如果仓库X可以提供仓库Y存储的所有内容,那么可以认为X是Y的一个镜像。下面的配置是中央仓库的一个镜像

    <mirror>  
      <id>maven-net-cn</id>  
      <name>Maven China Mirror</name>  
      <url>http://repo1.maven.org/maven2/</url>  
      <mirrorOf>central</mirrorOf>  
    </mirror>
5. 生命周期和插件

Maven的生命周期是一个抽象的概念,每个阶段都有对应的生命周期,生命周期本身不做什么事,所有的工作是由插件完成。


image.png

Maven有三套生命周期,相互独立,分别是cleandefaultsite
生命周期与插件的绑定实际是生命周期阶段和插件的目标(一个插件可以有多个目标)之间的绑定。

image.png

default 生命周期阶段与插件目标的绑定比较复杂,具体使用哪个插件的目标是与打包类型有关的。

image.png

上面这些生命周期阶段与插件目标的绑定是Maven的内置绑定,当然了开发人员也可以自定义绑定。

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
  • 插件配置
    <1>命令行传参
    用户可以通过命令行传参的方式调整插件的行为,比如不编译和执行测试用例
mvn install -Dmaven.test.skip=true

其中maven.test.skip 就是插件 maven-surfire-plugin 的参数

<2>POM全局配置
有些参数的值从项目创建到项目的发布都不会改变,或很少改变,对于这种情况,可以在POM中一次性配置好参数。所有基于该插件目标的任务,都会使用这些参数。

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

通过上面的配置,不管是maven-complier-plugincompile 目标还是 testCompiler 目标,都会基于 java 1.7 编译。

<3>POM中插件任务配置
也可以针对不同的任务(目标+生命周期阶段)配置不同的参数

           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.3</version>
                <executions>
                    <execution>
                        <id>ant-validate</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>I`m bound to validate phase.</echo>
                            </tasks>
                        </configuration>
                    </execution>
                    <execution>
                        <id>ant-verify</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <echo>I`m bound to verify phase.</echo>
                            </tasks>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

给插件 maven-antrun-pluginrun 目标,绑定不同的阶段,传递不同的任务参数

<4>查看插件的详情
https://maven.apache.org/plugins/index.html

mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin   Ddetail=true
Name: Maven Compiler Plugin
Description: The Compiler Plugin is used to compile the sources of your
  project.
Group Id: org.apache.maven.plugins
Artifact Id: maven-compiler-plugin
Version: 2.1
Goal Prefix: compiler

This plugin has 3 goals:

compiler:compile
  Description: Compiles application sources
  Implementation: org.apache.maven.plugin.CompilerMojo
  Language: java
  Bound to phase: compile

  Available parameters:

    compilerArgument
      Sets the unformatted argument string to be passed to the compiler if fork
      is set to true.

      This is because the list of valid arguments passed to a Java compiler
      varies based on the compiler version.

    compilerArguments
      Sets the arguments to be passed to the compiler (prepending a dash) if
      fork is set to true.
      .....

这里截取了一部分输出。
有两个字段需要说明: Goal Prefix 表示前缀,可以理解为插件名称的简写,Bound to phase 默认绑定的生命周期阶段

<5>从命令行调用插件

mvn -h
usage: mvn [options] [<goal(s)>] [<phase(s)>]

mvn 不仅可以调用生命周期阶段(mvn install),还可以直接调用插件的目标(mvn dependency:tree)。
有些插件的目标并不需要绑定到生命周期,比如 maven-help-plugin:describemaven-dependency-plugin:tree

  • 插件解析
mvn help:system

这条命令的 help 指的是 maven-help-plugin的前缀,system 是目标。怎么根据前缀找到对应的插件呢?
<1>插件仓库
和依赖构建一下,插件构建也有自己的仓库。以下是一个配置实例

      <pluginRepositories>
            <pluginRepository>
                <id>pluginRepository-shuzun</id>
                <url>http://ip:port/nexus/content/groups/public/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
             </pluginRepository>
        </pluginRepositories>

<2>版本
如果插件没有指定版本,并且在超级POM中也没有指定,则会通过遍历本地库和远程库,归并元数据(groupId/artifactId/maven-metadata.xml),在Maven3中,使用release。一般最好指定版本。

<3>前缀
插件前缀与 groupId:artifactId 一一对应,这种对应关系存储在仓库的 groupId/maven-metadata.xml 元数据中。maven默认会检查groupId为 org.apache.maven.pluginsorg.codehaus.mojo ,也可以通过配置 settings.xml ,让Maven检查其他的groupId上的插件仓库元数据

<pluginGroups>
    <!-- pluginGroup
     | Specifies a further group identifier to use for plugin lookup.
    <pluginGroup>com.your.plugins</pluginGroup>
    -->
  </pluginGroups>

<4>默认的groupId
如果插件的groupIdmaven.apache.maven.plugins,可以省略不写 groupId

6.聚合与继承
  • 聚合
    一次构建多个模块,下面是一个聚合POM的样例
 <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibai.test</groupId>
    <artifactId>aggregator</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Learning more about maven</name>

    <modules>
        <module>./module1</module>
        <module>./module2</module>
    </modules>

有三点需要注意
<1> packaging 必须为 pom ,否则无法构建
<2> 聚合模块不需要主代码,只要一个pom文件就可以了
<3> module元素的值是模块目录名相对于当前pom文件的路径,一般与模块的 artifactId 保持一致

  • 继承
    实现复用
    以下是一个实例
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ibai.test</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Learning more about maven -parent</name>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>module3</artifactId>
    <name>Learning more about maven - module1</name>
    <parent>
        <groupId>com.ibai.test</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../parent/pom.xml</relativePath>
    </parent>

说明
<1> relativePath 指定父POM文件的路径,默认是 ../pom.xml

  • 可继承的POM元素
    groupId
    versionId
    description
    organization:项目的组织信息
    inceptionYear:项目的创始年份
    url:项目的URL地址
    developers
    contributors
    distributionManagement:项目的部署配置
    issueManagement:项目的缺陷跟踪系统信息
    ciManagement:项目的持续集成系统信息
    scm:项目的版本控制系统信息
    properties:自定义属性
    dependencies
    dependencyManagement
    repositories
    build
    reporting

dependencyManagement 管理依赖,但不引入实际的依赖构建,一般让子模块继承父模块的 dependencyManagement 更灵活

  • 约定优于配置
    主代码路径,构建输出路径等信息都是在超级POM中定义了。

  • 反应堆
    反应堆就是包含了各模块之间继承和依赖的关系,从而能够自动计算出合理的模块构建顺序

裁剪反应堆
-am,同时构建所列模块的依赖模块
-amd,同时构建依赖于所列模块的模块
-pl,构建指定的模块,多个模块之间用逗号分隔
-rf,从指定的模块回复反应堆

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • maven maven是一个跨平台的项目管理的工具。隶属于Apache下的一个开源项目。主要服务于Java平台的项...
    jwfy阅读 874评论 0 2
  • 1. 什么是maven 翻译为“专家”,“内行” Maven是跨平台的项目管理工具。主要服务于基于Java平台的项...
    六月星空2011阅读 430评论 0 1
  • 在项目中Maven用的一直比较多,以前只知道简单的配置一些依赖,所以找了时间孔浩老师Maven的学习视频学习了一下...
    MPPC阅读 1,853评论 1 14
  • Maven概述 Maven定义Maven是一个项目管理和整合,统一管理jar包的工具;Maven为开发者提供了一套...
    THQ的简书阅读 793评论 0 0
  • 参考:https://blog.csdn.net/u013033112/article/details/80618...
    惜小八阅读 270评论 0 0