来源于:http://www.jianshu.com/p/0fb5e3fb704d

maven至今还是Java编程语言构建的事实标准,大部分项目还在使用maven来进行构建,因此了解maven内部运行的原理对定位和分析问题还是很有裨益的。本篇文章主要介绍一些maven内部运行过程中的一些基本概念,相信看完后,对那么些刚刚接触maven的读者来说maven将不再陌生。
  在具体分析项目构建的过程前,需要了解maven的一些基本概念,这些概念十分重要,请务必理解清楚后再看下文。基本概念主要有:POM,Lifecycle。这两个概念又会包含一些小的概念,下文会逐步讲解。
  POM: 注意这里的POM不是maven中构建过程使用的配置文件pom.xml,但他们之间还是有联系的。POM的全称是Project Object Model,用通俗点的话说就是对要构建的项目进行建模,将要构建的项目看成是一个对象(Object),后文就使用PO来指代这个对象。既然是一个对象,那么PO有哪些属性呢?在maven中一个项目都是用一个唯一的坐标(coordinate)来表示,坐标由groupId, artifactId, version, classifier, type这五部分组成。这样来说PO应该也要具备坐标属性。另外一方面,一个项目肯定不是孤立存在的,可能依赖于其他的一些项目,那么也就是说PO应该具备dependencies这个属性,用来表示其所依赖的外部项目。我们可以尝试一下用Java代码来描述下PO这个对象:

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

  我们知道XML的表达能力是很强大的,一个Java中的对象是可以用XML来描述,例如一个上面定义的PO对象则可以用下面的XML来描述(表达有不规范之处,理解其中的含义即可):

<PO>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<classifier><classifier>
<type></type>
<dependencies>
<PO></PO>
<PO></PO>
...
</dependencies>
</PO>

是不是好像和什么有点类似?对,就是pom.xml。pom.xml就是PO对象的XML描述。上面的PO定义还不完整,我们继续看下PO还有什么其他的属性。我们知道在Java中类是可以继承的,一个对象在创建的时候会同时创建其父类对象,类似的,PO对象也有其父对象,用parent属性来表示,并且PO对象会继承其父对象的所有属性。另外一方面,一个项目可能根据不同职责分为多个模块(module),所有模块其实也就是一个单独的项目,只不过这些项目会使用其父对象的一些属性来进行构建。我们将这些新的属性加到PO的定义中去:

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;
}

再将这个定义用XML语言表示一下:

<PO>
<parent></parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<classifier><classifier>
<type></type>
<dependencies>
<PO></PO>
<PO></PO>
...
</dependencies>
<modules>
...
</modules>
</PO>

是不是越来越像pom.xml了?对,这就是pom.xml的由来。再说一遍:pom.xml就是PO对象的XML描述。到此为止,相信你再看pom.xml文件时,会有一个全新的认识。

  上面说的这些PO属性是项目的一些固有属性,到目前为止,我们还没有涉及项目的构建过程。构建过程对应的是PO对象的build属性,那么你应该马上想到,在pom.xml中就是<build>元素中的内容。这里就有引入maven中第二个核心概念:Lifecycle。Lifecycle直译过来就是生命周期。我们平常会接触到哪些周期呢?一年中春夏秋冬就是一个周期。一个周期中可能分为多个阶段,比如这里的春夏秋冬。在maven中一个构建过程就对应一个Lifecycle,这个Lifecycle也分为多个阶段,每个阶段叫做phase。你可能会问,那这个Lifecycle中包含多少个phase呢?一个标准的构建Lifecycle包含了如下的phase:

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:将打包产物安装到远程仓库

  在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>元素中配置即可。例如:

<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>

就将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之间的关系:

Lifecyle-phase-plugin-goal关系图

到此为止,相信对于POM, pom.xml,Lifecycle, phase, goal这些概念应该十分清楚了。

maven内部运行原理解析(一)的更多相关文章

  1. maven内部运行原理解析

    maven至今还是Java编程语言构建的事实标准,大部分项目还在使用maven来进行构建,因此了解maven内部运行的原理对定位和分析问题还是很有裨益的.本篇文章主要介绍一些maven内部运行过程中的 ...

  2. (转)Apache和Nginx运行原理解析

    Apache和Nginx运行原理解析 原文:https://www.server110.com/nginx/201402/6543.html Web服务器 Web服务器也称为WWW(WORLD WID ...

  3. View Animation 运行原理解析

    Android 平台目前提供了两大类动画,在 Android 3.0 之前,一大类是 View Animation,包括 Tween animation(补间动画),Frame animation(帧 ...

  4. JavaScript运行原理解析

    原文:1.http://blog.csdn.net/liaodehong/article/details/50488098 2.Stack的三种含义 (阮一峰) 3. http://lib.csdn. ...

  5. .NET CORE学习笔记系列(5)——ASP.NET CORE的运行原理解析

    一.概述 在ASP.NET Core之前,ASP.NET Framework应用程序由IIS加载.Web应用程序的入口点由InetMgr.exe创建并调用托管,初始化过程中触发HttpApplicat ...

  6. 转:Apache和Nginx运行原理解析

    Web服务器 Web服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务. 应用层使用HTTP协议. HTML文档格式. 浏览器统一资源定位器(URL). Web服 ...

  7. View 动画 Animation 运行原理解析

    这次想来梳理一下 View 动画也就是补间动画(ScaleAnimation, AlphaAnimation, TranslationAnimation...)这些动画运行的流程解析.内容并不会去分析 ...

  8. Apache和Nginx运行原理解析

    Web服务器 Web服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务. 应用层使用HTTP协议. HTML文档格式. 浏览器统一资源定位器(URL). Web服 ...

  9. 转载-Apache和Nginx运行原理解析

    本文只作为了解Apache和Nginx知识的一个梳理,想详细了解的请阅读文末参考链接中的博文. Web服务器 Web服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览 ...

随机推荐

  1. 手机应用:非功能需求 Check List

    服务状态防止并发 网络保持:无线网络,GPRS 网络连接:https,手机助手代理 电量 屏幕保持防止休眠 下载重试机制 定时检查XML 限速下载,线程休眠 下载出错反馈机制 消息广播 状态栏通知 进 ...

  2. java中ant包中的org.apache.tools.zip实现压缩和解压缩

    其实apache中的ant包(请自行GOOGLE之ant.jar)中有一个更好的类,已经支持中文了,我们就不重复制造轮子了,拿来用吧,这里最主要的功能是实现了 可以指定多个文件 到同一个压缩包的功能 ...

  3. 解决Sqoop报错Could not load db driver class: com.intersys.jdbc.CacheDriver

    报错栈: // :: INFO tool.CodeGenTool: Beginning code generation // :: ERROR sqoop.Sqoop: Got exception r ...

  4. 混沌数学之Chua's circuit(蔡氏电路)

    蔡氏电路(英语:Chua's circuit),一种简单的非线性电子电路设计,它可以表现出标准的混沌理论行为.在1983年,由蔡少棠教授发表,当时他正在日本早稻田大学担任访问学者[1].这个电路的制作 ...

  5. Informatica 常用组件Filter之四 优化

    以下提示可提高过滤器性能: 在映射中先使用过滤器转换. 要使会话性能最忧化,应使过滤器转换尽可能靠近映射中的源.并不是将您准备放弃的行传递至映射,而是在随后从源至目标的数据流中过滤出不需要的数据. 使 ...

  6. 线程 Timer TimerTask 计时器 定时任务 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. c#写扩展方法

    学习MVC时,学会了写扩展方法,用起来很方便. 01 using System; 02 using System.Collections.Generic; 03 using System.Linq; ...

  8. .NET/Mysql-petatoco连接mysql数据库

    安装mysql数据库 用nugget添加.net连接mysql数据库的组件

  9. C# 使用Newtonsoft.Json序列化自定义类型

    Json.Net是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Linq To JSON可以快速的读写Json,通过JsonSerializ ...

  10. ASP.NET WebServices 因 URL 意外地以“/HelloWorld”结束,请求格式无法识别。

    今天在使用Asp.net做一个WebServices时通过Get方式调用方法时却出现了以下错误(仅在Get请求下,POST下正常)   在网络和MSDN上了解到WebServices默认只启用 Htt ...