maven内部运行原理解析

作者: 编程应用  发布:2019-10-04

maven到现在仍然Java编制程序语言营造的事实规范,半数以上品种还在动用maven来扩充营造,由此领会maven内部运营的法规对确定地点和深入分析难题要么很有实益的。本篇作品首要介绍一些maven内部运行进程中的一些基本概念,相信看完后,对那么些刚刚接触maven的读者来讲maven将不再面生。 在具体剖判项目塑造的进程前,必要驾驭maven的一部分基本概念,那个概念足够至关首要,请必得领会明白后再看下文。基本概念首要有:POM,Lifecycle。那三个概念又会含有部分小的定义,下文种渐渐疏解。 POM: 注意这里的POM不是maven中创设进程使用的安顿文件pom.xml,但他俩之间依然有牵连的。POM的完备是Project Object Model,用通俗点的话说正是对要营造的类型进展建立模型,将在创设的类型作为是三个对象,后文就动用PO来指代这些目的。既然是一个指标,那么PO有怎样属性呢?在maven中叁个种类都以用二个独一的坐标(coordinate)来代表,坐标由groupId, artifactId, version, classifier, type那五片段构成。那样的话PO应该也要享有坐标属性。别的一边,八个门类必然不是孤立存在的,大概凭仗于任何的一部分项目,那么也正是说PO应该具有dependencies那脾特性,用来代表其所正视的外表项目。大家得以品尝一下用Java代码来描述下PO那些指标:

在率先篇里首要介绍了maven的多少个大旨概念,这一篇里大家就以多个简易的事例来分析任何maven运维的长河。营造所使用的品类布局如下:

class PO{ private String groupId; private String artifactId; private String version; private String classifier; private String type; private Set<PO> dependencies;}

图片 1项目结构首假如贰个echo项目,其饱含了七个module,分别是api和biz。echo项目标pom.xml的从头到尾的经过如下:

笔者们明白XML的表达本领是很有力的,二个Java中的对象是足以用XML来陈说,比如二个方面定义的PO对象则足以用上边包车型客车XML来说述(表达有不正规之处,领悟当中的含义就能够):

<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>org.maven</groupId> <artifactId>echo</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <module>api</module> <module>biz</module> </modules></project>
<PO> <groupId></groupId> <artifactId></artifactId> <version></version> <classifier><classifier> <type></type> <dependencies> <PO></PO> <PO></PO> ... </dependencies></PO>

此地有个比较费解的地点便是<packaging>pom</packaging>。若<packaging>成分的内容是jar,那么大家很好驾驭,相当于说那些类型最后会被打包成三个jar包。那<packaging>成分为pom又是何等意思呢?从字面上的情趣来看,那些类型将打包成二个pom。大家无妨去maven仓库里去瞧瞧(前提是早已在等级次序下运作了mvn install命令)。大家开采在<maven仓库路线>/org/maven/echo/1.0.0目录下有五个echo-1.0.0.pom文件,留心的读者只怕早就发掘那个文件其实和echo项目中的pom.xml是同贰个文书。这样做的指标是怎么着吗?还记得首先篇中说过的PO对象啊,大家说过PO对象也可能有一而再关系的,比方说这里echo项目相应的PO对象就是api项目相应的PO对象的父对象(api项目是echo项目标贰个module,在api项指标pom.xml中<parent>成分的剧情所对应的正是echo项目),而echo项目PO对象的父对象又是哪个吧?答案是Super POM对应的PO对象。这正是maven中project inheritance的定义。当实际进行maven命令的时候,会基于project inheritance关系对项指标pom.xml实行转向,得到实在试行时所用到的pom.xml,即所谓的effective pom。而<packaging>pom</packaging>的效能就在此地。因而得以获得多个定论:全部<packaging>成分为pom的花色实际并不会输出贰个可供外界使用,类似于jar包的事物。那类项目标职能有多个:

是还是不是近乎和怎么有一些类似?对,就是pom.xml。pom.xml就是PO对象的XML描述。上边包车型大巴PO定义还不完全,大家三番七次看下PO还应该有哪些其余的质量。大家了然在Java中类是足以继续的,二个目的在创建的时候会同期创建其父类对象,类似的,PO对象也是有其父对象,用parent属性来代表,並且PO对象会延续其父对象的装有属性。别的一头,三个类型恐怕基于区别职责分为三个模块,全数模块其实也正是三个单独的花色,只可是那些品种会选取其父对象的一对属性来展开创设。大家将那么些新的属性加到PO的定义中去:

  • 管理子项目诸如这里的api和biz正是echo项目标七个module。若未有echo这些父项目,我们需求到api和biz七个品种下分别推行mvn install命令技能做到全套塑造进度,而有了echo这一个父项目之后,我们只需在echo项目中实施mvn install就可以,maven会分析pom.xml,开掘该类型有api和biz八个module,它会分别到那三个品类下去实行mvn install命令。当module数量相当多的时候,能大大进步塑造的频率。

  • 管理持续属性譬喻api和biz都须要有些正视,那么在echo项指标pom.xml中扬言就可以,因为依照PO对象的承继关系,api和biz项目会承接echo项指标凭仗,那样就足以减弱部分再度的输入。

class PO{ private String groupId; private String artifactId; private String version; private String classifier; private String type; private Set<PO> dependencies; private PO parent; private Set<PO> modules;}

effective pom包罗了脚下项目标PO对象,直到Super POM对应的PO对象中的消息。要看三个品种的effective pom,只需在品种中实践

再将以此定义用XML语言表示一下:

mvn help:effective-pom
<PO> <parent></parent> <groupId></groupId> <artifactId></artifactId> <version></version> <classifier><classifier> <type></type> <dependencies> <PO></PO> <PO></PO> ... </dependencies> <modules> ... </modules></PO>

指令即可查看。这里顺带说一句,有的同学只怕不知道地方这些命令是何等看头。maven命令的语法为

是还是不是进一步像pom.xml了?对,那正是pom.xml的由来。再说一回:pom.xml正是PO对象的XML描述。到此甘休,相信您再看pom.xml文件时,会有二个簇新的认知。

mvn [options] [goal] [phase]

地点说的这么些PO属性是项目标有的原始属性,到方今截至,大家还不曾关联项指标营造进度。营造进度对应的是PO对象的build属性,那么你应该立即想到,在pom.xml中正是<build>成分中的内容。这里就有引进maven中第四个基本概念:Lifecycle。Lifecycle直译过来正是生命周期。大家平日会接触到怎么周期呢?一年中春夏季新秋冬就是三个周期。四个周期中大概分为多少个等级,举个例子此处的春夏季商节冬。在maven中多个营造进度就相应叁个Lifecycle,那一个Lifecycle也分为八个等第,每一种阶段叫作phase。你或者会问,那这几个Lifecycle中蕴含多少个phase呢?一个标准的创设Lifecycle包蕴了之类的phase:

此地出现了第一篇中描述的四个概念:goal和phase。maven允许你实行三个依旧七个goals/phases。很鲜明那面包车型客车命令help:effective-pom实际不是多个phase(maven塑造进程中的phase请参谋上一篇小说),那么也便是说它是三个goal。对那些goal只不过是运用了缩写的款型,其全称是那般的:

validate: 用于验证项目的有效性和其项目所需要的内容是否具备initialize:初始化操作,比如创建一些构建所需要的目录等。generate-sources:用于生成一些源代码,这些源代码在compile phase中需要使用到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:集成测试后置操作install:将打包产物安装到本地maven仓库deploy:将打包产物安装到远程仓库
org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom

在maven中,你实施另外一个phase时,maven会将其在此以前的phase都实践。比方 mvn install,那么maven会将deploy之外的全数phase依据他们出现的逐一一回实行。 Lifecycle还牵涉到另外三个万分重要的定义:goal。注意上面Lifecycle的概念,约等于说maven为顺序的营造定义了一套规范流程:第一步需求validate,第二步供给initialize... ... compile,test,package,... ... install,deploy,可是并从未定义每一个phase具体应该怎样操作。这里的phase的意义有一点点类似于Java语言中的接口,只协商了二个左券,但并从未概念具体的动作。比方说compile那个phase定义了在创设流程中须要经过编写翻译这些阶段,但未有定义应该怎么编译(编写翻译的输入是怎么着?用什么样编写翻译javac/gcc?)。这里具体的动作正是由goal来定义,多少个goal在maven中便是贰个Mojo(Maven old java object)。Mojo抽象类中定义了一个execute()方法,三个goal的实际动作正是在execute()方法中贯彻。完毕的Mojo类应该放在哪儿吗?答案是maven plugin里,所谓的plugin其实也便是二个maven项目,只可是这么些种类会援引maven的有的API,plugin项目也可以有所maven坐标。 在实施实际的创设时,我们必要为lifecycle的各样phase都绑定一个goal,那样技巧够在种种步骤实施一些切实的动作。例如在lifecycle中有个compile phase规定了创设的流程必要经过编写翻译那么些手续,而maven-compile-plugin那么些plugin有个compile goal就是用javac来将源文件编写翻译为class文件的,大家需求做的就是将compile这些phase和maven-compile-plugin中的compile这么些goal实行绑定,那样就足以达成Java源代码的编写翻译了。有一点点绕,多看几次。那么有人就能问,在哪个地方绑定呢?答案是在pom.xml<build>成分中计划就能够。举个例子:

以分行为分隔符,满含了groupId,artifactId,version,goal四有的。若groupId为org.apache.maven.plugins则足以运用上述的简写情势。也正是说

<build><plugins> <plugin> <artifactId>maven-myquery-plugin</artifactId> <version>1.0</version> <executions> <execution> <id>execution1</id> <phase>test</phase> <configuration> <url>http://www.foo.com/query</url> <timeout>10</timeout> <options> <option>one</option> <option>two</option> <option>three</option> </options> </configuration> <goals> <goal>query</goal> </goals> </execution> </executions> </plugin></plugins></build>
mvn help:effective-pommvn org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom

就将maven-myquery-plugin中的query那些goal绑定到了test那个phase,后续在maven实施到test phase时就能实施query goal。还也可能有有人只怕会问,笔者都尚未点名Java源文件的任务,编写翻译啥?那就引出了maven的design principle。在maven中,有二个十二分出名的principle就是convention over configuration。这点和ant有那多少个大的分别,举个例子利用ant来开展编写翻译时,大家须求钦定源文件的职位,输出文件的职位,javac的地方,classpath... ...在maven中那几个都以没有须求,若未有手动配置,maven暗中认可从<项目根目录>/src/main/java那些目录去查找Java源文件,编写翻译后的class文件会保留在<项目根目录>/target/classes目录。在maven中,全部的PO都有多少个根对象,正是Super POM。Super POM中定义了具备的私下认可的配置项。Super POM对应的pom.xml文件能够在maven安装目录下lib/maven-model-builder-3.0.3.jar:org/apache/maven/model/pom-4.0.0.xml中找到。用一张图来代表maven Lifecycle,phase,goal之间的关联:

是等价的,都以实行了maven-help-plugin那几个plugin中的effective-pom那个goal。

图片 2Lifecyle-phase-plugin-goal关系图

好了,继续回到effective pom。大家说过maven在真正营造的时候用的正是effective pom,那么表明effective pom中带有了创设的有着音讯,大家以biz项目中的effective pom为例来看下effective pom长什么样体统。在biz项目中实施mvn help:effective-pom命令,你会赢得如下输出:

到此结束,相信对于POM, pom.xml,Lifecycle, phase, goal那个概念应该格外亮堂了。还极度?请留言。

 <?xml version="1.0"?> <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> <parent> <groupId>org.maven</groupId> <artifactId>echo</artifactId> <version>1.0.0</version> </parent> <groupId>org.maven</groupId> <artifactId>echo-biz</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>org.maven</groupId> <artifactId>echo-api</artifactId> <version>1.0.0</version> <scope>compile</scope> </dependency> </dependencies> <build> <sourceDirectory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/main/java</sourceDirectory> <scriptSourceDirectory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/main/scripts</scriptSourceDirectory> <testSourceDirectory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/test/java</testSourceDirectory> <outputDirectory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/target/classes</outputDirectory> <testOutputDirectory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/target/test-classes</testOutputDirectory> <resources> <resource> <directory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/main/resources</directory> </resource> </resources> <testResources> <testResource> <directory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/test/resources</directory> </testResource> </testResources> <directory>/Users/allstarw/workspace/own-proj/misc/maven/echo/biz/target</directory> <finalName>echo-biz-1.0.0</finalName> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <id>default-clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.3.1</version> <executions> <execution> <id>default-install</id> <phase>install</phase> <goals> <goal>install</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>default-resources</id> <phase>process-resources</phase> <goals> <goal>resources</goal> </goals> </execution> <execution> <id>default-testResources</id> <phase>process-test-resources</phase> <goals> <goal>testResources</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.10</version> <executions> <execution> <id>default-test</id> <phase>test</phase> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <id>default-testCompile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> <execution> <id>default-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <id>default-jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.7</version> <executions> <execution> <id>default-deploy</id> <phase>deploy</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>

篇幅有一点长,省略了有的内容。相比较biz项指标pom.xml,大家发掘effective pom中追加了Super POM中持续过来的有个别布局,比方说<sourceDirectory>定义了biz项目标源码路线,以及Lifecycle中逐个phase绑定的goal:

[phase] [goal]compile maven-compiler-plugin:2.3.2:compilepackage maven-jar-plugin:2.3.2:jarinstall maven-install-plugin:2.3.1:install... ...

有了effective pom的概念之后,再来看maven创设的输出日志,是还是不是有些柳暗花明的感觉?

[INFO] Scanning for projects...[INFO] ------------------------------------------------------------------------[INFO] Reactor Build Order: [INFO] [INFO] echo[INFO] echo-api[INFO] echo-biz[INFO] [INFO] ------------------------------------------------------------------------[INFO] Building echo 1.0.0[INFO] ------------------------------------------------------------------------[INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ echo ---[INFO] Installing /Users/allstarw/workspace/own-proj/misc/maven/echo/pom.xml to /Users/allstarw/.m2/repository/org/maven/echo/1.0.0/echo-1.0.0.pom[INFO] [INFO] ------------------------------------------------------------------------[INFO] Building echo-api 1.0.0[INFO] ------------------------------------------------------------------------[INFO] [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ echo-api ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory /Users/allstarw/workspace/own-proj/misc/maven/echo/api/src/main/resources[INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ echo-api ---[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent![INFO] Compiling 1 source file to /Users/allstarw/workspace/own-proj/misc/maven/echo/api/target/classes[INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ echo-api ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory /Users/allstarw/workspace/own-proj/misc/maven/echo/api/src/test/resources[INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ echo-api ---[INFO] No sources to compile[INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ echo-api ---[INFO] No tests to run.[INFO] Surefire report directory: /Users/allstarw/workspace/own-proj/misc/maven/echo/api/target/surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Results :Tests run: 0, Failures: 0, Errors: 0, Skipped: 0[INFO] [INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ echo-api ---[INFO] Building jar: /Users/allstarw/workspace/own-proj/misc/maven/echo/api/target/echo-api-1.0.0.jar[INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ echo-api ---[INFO] Installing /Users/allstarw/workspace/own-proj/misc/maven/echo/api/target/echo-api-1.0.0.jar to /Users/allstarw/.m2/repository/org/maven/echo-api/1.0.0/echo-api-1.0.0.jar[INFO] Installing /Users/allstarw/workspace/own-proj/misc/maven/echo/api/pom.xml to /Users/allstarw/.m2/repository/org/maven/echo-api/1.0.0/echo-api-1.0.0.pom[INFO] [INFO] ------------------------------------------------------------------------[INFO] Building echo-biz 1.0.0[INFO] ------------------------------------------------------------------------[INFO] [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ echo-biz ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory /Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/main/resources[INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ echo-biz ---[INFO] Nothing to compile - all classes are up to date[INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ echo-biz ---[debug] execute contextualize[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory /Users/allstarw/workspace/own-proj/misc/maven/echo/biz/src/test/resources[INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ echo-biz ---[INFO] No sources to compile[INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ echo-biz ---[INFO] No tests to run.[INFO] Surefire report directory: /Users/allstarw/workspace/own-proj/misc/maven/echo/biz/target/surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Results :Tests run: 0, Failures: 0, Errors: 0, Skipped: 0[INFO] [INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ echo-biz ---[INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ echo-biz ---[INFO] Installing /Users/allstarw/workspace/own-proj/misc/maven/echo/biz/target/echo-biz-1.0.0.jar to /Users/allstarw/.m2/repository/org/maven/echo-biz/1.0.0/echo-biz-1.0.0.jar[INFO] Installing /Users/allstarw/workspace/own-proj/misc/maven/echo/biz/pom.xml to /Users/allstarw/.m2/repository/org/maven/echo-biz/1.0.0/echo-biz-1.0.0.pom[INFO] ------------------------------------------------------------------------[INFO] Reactor Summary:[INFO] [INFO] echo .............................................. SUCCESS [0.461s][INFO] echo-api .......................................... SUCCESS [2.581s][INFO] echo-biz .......................................... SUCCESS [0.382s][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 3.593s[INFO] Finished at: Wed Jul 06 00:22:50 CST 2016[INFO] Final Memory: 10M/156M[INFO] ------------------------------------------------------------------------

日志的输出十三分了解,分别创设echo,api,biz那四个档期的顺序(因为biz项目信任api项目,由此api项目必要首先营造)。对每种门类营造时,将lifecycle中的phase所对应的goal依次推行。今后你可以看懂maven的出口日志了啊?还会有毛病?请留言。

本文由金沙澳门官网送注册58发布于编程应用,转载请注明出处:maven内部运行原理解析

关键词: