maven基础

坐标

maven管理项目依赖的底层基础-坐标。坐标元素:groupId、artifactId、version、packaging、classifier。

<dependency>
         <groupId>org.apache.pig</groupId>
         <artifactId>pig</artifactId>
         <classifier>h2</classifier>
         <version>0.15.0</version>
         <scope>provided</scope>
</dependency>

groupId:定义当前maven项目隶属的实际项目。
artifactId:定义实际项目中的一个maven项目(模块),推荐的做法是使用实际项目名作为artifactId的前缀。
version:定义maven项目当前所处的版本。
packaging:定义maven项目的打包方式。默认使用jar。
classifier:定义用来帮助定义构建输出的一些附属构件。例如xxx-1.0-javadoc.jar和xxx-1.0-sources.jar就包含了java文档和源代码。注意:不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。
groupId、artifactId、version是必须定义的,packaging是可选的,classifier是不能直接定义的。
项目构件的文件名一般的规则为artifactId-version [-classifier].packaging。

依赖

依赖配置

            <dependency>
                <groupId>org.apache.storm</groupId>
                <artifactId>storm-core</artifactId>
                <version>${storm.version}</version>
                <scope>provided</scope>
                <type>jar</type>
                <optional>true</optional>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

type:依赖的类型,对应于项目坐标定义的packaging。
scope:依赖的范围。
optional:标记依赖是否可选。
exclusions:用来排除传递性依赖。

依赖范围

缘由:首先,maven在编译项目主代码的时候需要使用一套classpath,需要的文件以依赖的方式被引入到classpath中。其次,maven在编译和执行测试的时候会使用另外一套classpath。最后,实际运行maven项目的时候,又会使用一套classpath。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系。
compile:编译依赖范围。默认的依赖范围。对于编译、测试、运行三种classpath都有效。
test:测试依赖范围。只对测试classpath有效。
provided:已提供依赖范围。对于编译和测试classpath有效,但在运行时无效。例如servlet-api。
runtime:运行时依赖范围。对于测试和运行时classpath有效,对编译主代码时无效。例如:jdbc,编译时只需要jdk提供的jdbc接口,只有在执行测试或者运行项目的时候才需要实现该接口的具体jdbc驱动。
system:系统依赖范围。同provided依赖范围。使用时必须通过systemPath元素显式指定依赖的文件的路径。此依赖不是通过maven仓库解析的,往往与本机系统绑定。
import:导入依赖范围。不会对三种classpath产生实际的影响。与dependencyManagement有关。

依赖范围与classpath的关系

传递性依赖

假如A依赖于B,B依赖于C,那么A对于B第一直接依赖,B对于C是第二直接依赖,A对于C是传递性依赖。
依赖范围不仅可以控制依赖与三种classpath的关系,还对传递性依赖产生影响。

依赖范围影响传递性依赖

注:左一列表示第一直接依赖范围,最上一行表示第二直接直接依赖范围,中间的交叉单元格则表示传递性依赖范围。

依赖调解

第一原则:路径最近者优先。
第二原则:第一声明者优先。在依赖路径长度相等的前提下,在pom中依赖声明的顺序决定了谁会被解析使用,顺序最靠前的那个依赖优胜。

可选依赖

可选依赖,可能项目实现了两个特性,特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。
可选依赖不会被传递,需要显式声明依赖。

依赖冲突

  • 使用exclusion元素
  • 直接引入需要的依赖

优化依赖

mvn dependency:list
mvn dependency:tree 详细了解项目中所有依赖的具体信息
mvn dependency:analyze 可以分析项目中使用到的,但没有显式声明的依赖;项目中未使用的,但显式声明的依赖。注意:只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖发现不了。

仓库

本地仓库
远程仓库:中央仓库,私服,其他公共库

SNAPSHOT
RELEASE

生命周期和插件

maven的生命周期是为了对所有的构建过程进行抽象和统一。这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建步骤。几乎所有项目的构建,都能映射到这样一个生命周期上。
maven的生命周期是抽象的,实际的任务都交由插件来完成。例如:maven-compiler-plugin针对编译的插件,maven-surefire-plugin针对测试的插件。

生命周期

maven有三套相互独立的生命周期,clean、default、site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,site生命周期的目的是建立项目站点。
每个生命周期包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段。执行某个阶段的时候,会顺序执行该阶段之前的所有阶段。

clean生命周期

pre-clean:执行一些清理前需要完成的工作
clean:清理上一次构建生成的文件
post-clean:执行一些清理后需要完成的工作

default生命周期

validate
initialize
generate-sources
process-sources:处理项目主资源文件
generate-resources
process-resources
compile:编译项目的主源码
process-classes
generate-test-sources
process-test-sources:处理项目测试资源文件
generate-test-resources
process-test-resources
test-compile:编译项目的测试代码
process-test-classes
test:使用单元测试框架运行测试,测试代码不会被打包或部署
prepare-package
package:接受编译好的代码,打包成可发布的格式
pre-integration-test
integration-test
post-integration-test
verify
install:将包安装到maven本地仓库,供本地其他maven项目使用
deploy:将最终的包复制到远程仓库,供其他开发人员和maven项目使用

site生命周期

pre-site:执行一些在生成项目站点之前需要完成的工作
site:生成项目站点文档
post-site:执行一些在生成项目站点之后需要完成的工作
site-deploy:将生成的项目站点发布到服务器上

命令行与生命周期

从命令行执行maven任务的最主要方式就是调用maven的生命周期阶段。
mvn clean
mvn test
mvn clean install
mvn clean deploy site-deploy

插件

插件目标

每个插件有很多功能,每个功能就是一个插件目标。
例如:maven-dependency-plugin的插件目标有dependency:analyze,dependency:tree等。冒号前面是插件前缀,冒号后面是该插件的目标。

插件绑定

maven的生命周期与插件项目绑定,用以完成实际的构建任务。

插件配置

聚合和继承

聚合

    <modules>
        <module>cpspool_index_base</module>
        <module>cpspool_index_batch</module>
        <module>cpspool_index_realtime</module>
        <module>cpspool_index_batch_signal_node</module>
        <module>cpspool_index_batch_create_index_node</module>
        <module>cpspool_index_batch_node</module>
        <module>cpspool_index_batch_online_index_node</module>
    </modules>
  • 目标
    一次构建多个项目,而不是到多个项目目录下分别构建。
  • 打包方式
    对于聚合模块,其打包方式packaging的值必须是pom,否则无法构建。
  • 目录结构
    可以是父子关系,可以是平行关系。

继承

    <parent>
        <artifactId>union_cpspool_index</artifactId>
        <groupId>com.jd.ads.union.cps</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
  • 目标
    消除重复和潜在的问题
  • 打包方式
    作为父模块的POM,打包类型也必须是pom。
  • 继承元素
    groupId
    version
    properties:自定义的maven属性
    dependencies:项目的依赖配置
    dependencyManagement:项目的依赖管理配置
    repositories:项目的仓库配置
    build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等。
  • dependencies和dependencyManagement
    继承父POM的dependencies后,可以移除子POM中的依赖配置,从而简化配置,但是无法确定将来添加的子模块是否一定需要父POM的所有配置。
    dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。
    import依赖范围,只在dependencyManagement元素下有效,使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。

聚合与继承的关系

聚合主要是为了方便快速构建项目,继承主要是为了消除重复配置。
对于聚合模块来说,它知道有哪些被聚合的模块,但那些被聚合的模块不知道这个聚合模块的存在。
对于继承关系的父POM来说,它不知道有哪些子模块继承于它,但那些子模块都必须知道自己的父POM是什么。

构建顺序

maven按序读取POM,如果该POM没有依赖模块,那么就构建该模块,否则就先构建其依赖模块,如果该依赖还依赖于其他模块,则进一步先构建依赖的依赖。

灵活性三大特性

属性

使用properties元素定义,使用${属性名称}的方式引用,可以消除重复。
内置属性:${basedir}表示项目跟目录,即包含pom.xml文件的目录;${version}表示项目的版本。
POM属性:可以引用POM文件对应的元素的值。${project.artifactId}
自定义属性:用户在properties元素自定义的属性。
Settings属性:引用settings.xml文件中XML元素的值,${settings.localRepository}
Java系统属性:
环境变量属性:

profile

根据环境不同进行不同的配置,例如数据库配置。
可以使用-P参数激活profile

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <deploy.type>dev</deploy.type>
            </properties>
        </profile>      
        <profile>
            <id>prod</id>
            <properties>
                <deploy.type>prod</deploy.type>
            </properties>
        </profile>    
    </profiles>

资源过滤

推荐

官网:http://maven.apache.org/
<<maven权威指南>>
教程:http://www.yiibai.com/maven/

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

推荐阅读更多精彩内容