Chapter 11. 构建Profile

11.1. Profile是用来做什么的?

Profile能让你为一个特殊的环境自定义一个特殊的构建;profile使得不同环境间构建的可移植性成为可能。

不同的构建环境是什么意思?构建环境的两个例子是产品环境和开发环境。当你在开发环境中工作时,你的系统可能被配置成访问运行在你本机的开发数据库实例,而在产品环境中,你的系统被配置成从产品数据库读取数据。Maven能让你定义任意数量的构建环境(构建profile),这些定义可以覆盖pom.xml中的任何配置。你可以配置你的应用程序,在“开发”profile中,访问本地的开发数据库实例,在“产品”profile中,访问产品数据库。Profile也可以通过环境和平台被激活,你可以自定义一个构建,它根据不同的操作系统或者不同的JDK版本有不同的行为。在我们讨论使用和配置Maven profile之前,我们需要定义构建可移植性的概念。

11.1.1. 什么是构建可移植性

一个构建的“可移植性”是指将一个项目在不同的环境中构建的难易度。一个不用做任何自定义配置或者属性文件配置就能工作的构建,比一个需要很多配置才能工作的构建,具有更高的可移植性。构建可移植性最高的项目往往是一些开源项目如Apache Commons或者Apache Velocity,它们自带Maven构建配置,不需要或者需要很少的自定义配置。简言之,可移植性最高的项目往往“开箱可用”,而可移植性最低的构建则需要你跳过一个个难缠的框框,配置平台相关的路径以定位构建工具。在我们展示如何实现构建移植性之前,先浏览一些不同种类的构建可移植性。

11.1.1.1. 不可移植构建

缺少可移植性正是所有构建工具试图防止的——然而,任何工具都能被配置成不可移植(即使Maven)。一个不可移植的项目只有在一组特定的环境和标准(比如,你的本地机器)下才能构建。除非你自己一个人工作,不打算将你的应用部署到其它机器上,否则最好完全避免不可移植性。一个不可移植的构建只能在单独的机器上运行,是“一次性的”。Maven设计提供了使用profile自定义构建的能力,阻止不可移植的构建。

当一个新的开发人员得到不可移植项目的源码的时候,如果不重写大部分的构建脚本,他就不能构建这个项目。

11.1.1.2. 环境可移植性

如果一个构建有一种机制,能针对不同的环境有特定的行为和配置,那么我们就说该构建具有环境可移植性。例如,一个项目在测试环境中包含一个对于测试数据库的引用,而在产品环境中则引用了产品数据库,那么该项目的构建是环境可移植的。这很有可能是因为该构建针对不同的环境有不同的属性组。当你转移到一个不同的环境中,该环境未被定义,也没有为其创建profile,那么项目将不能工作。因此,该项目也只是在已定义的环境中可移植。

当一个新的开发人员得到环境可移植项目的源码,他们必须在已定义的环境中运行此构建,否则就需要创建自定义的环境才能构建此项目。

11.1.1.3. 组织(内部)可移植性

这一层可移植性的中心是一个项目可能需要访问一些内部资源如源码控制系统或者内部维护的Maven仓库。大公司的项目可能依赖于一个只对内部开发人员可用的数据库,一个开源项目可能需要一个特定级别的证书来发布web站点,以及将构建的产品发布到公共仓库。

如果你试图在内网外部(例如,在公司的防火墙外面)从零开始构建一个内部项目,构建会失败。它失败的原因可能是一些必须的自定义插件不可用,或者项目的依赖找不到,因为你没有适当的证书从一个自定义的远程仓库获取依赖。这样的项目只在一个组织内部的环境中拥有可移植性。

11.1.1.4. 广泛(全局)可移植性

任何人都可以下载具有广泛可移植性项目的源码,不用为特定的环境自定义构建就能进行编译,安装。这是最高级别的可移植性;构建这样的项目不需要做任何额外的工作。该级别的可移植性对开源项目尤为重要,因为开源项目的潜在贡献者需要能很方便的下载源码进行构建。

任何一个开发者都可以下载具有广泛可移植性项目的源码。

11.1.2. 选择一个适当级别的可移植性

很显然,你需要避免创建出最坏的情况:不可移植构建。你可能不幸需要在这样的一个组织工作或学习:其核心应用的构建是不可移植的。在这样的组织下,没有特定的人员或机器的帮助,你就不可能部署一个应用。如果不和那个维护该不可移植构建的人协调,很难引入新的项目依赖或变化。当个人或小组需要控制项目如何以及何时构建部署的时候,不可移植构建就会由于一些政治环境因素高速增长。“我们该如何构建该系统?哦,我们需要找到Jack,让他帮我们构建,没有其他人能将其部署到产品环境中”这是一种非常危险的情形,该情形比你想象的普遍得多。如果你为这样的一个组织工作,Maven和Maven profile能帮你脱离困境。

与之完全相反的可移植性范围是广泛可移植性构建。总的来说广泛可移植性构建是最难达到的构建系统。这样的构建严格要求你依赖的项目和工具是免费分发的,在公共环境中可用。很多商业软件包可能被排除在这种可移植性最高的构建外面,因为只有在接受某个许可证后你才能下载它们。广泛可移植性也限制它的依赖能以Maven构件的形式分发。例如,如果你依赖于Oracle JDBC驱动,你的用户就需要手工下载安装它们;这就不是广泛可移植性,因为你必须为那些有兴趣构建你应用的人发布一组关于创建环境的指令。而另一方面,你可以使用一个在公共Maven仓库中可用的JDBC驱动如MySQL或者HSQLDB。

如之前叙述的那样,开源项目从拥有最广泛的可移植性构建获益。广泛可移植性构建降低了为开源项目做贡献的低效性。在一个开源项目(如Maven)中,有两个单独的组:最终用户和开发者。当一个项目的最终用户决定为项目贡献一个补丁,它们就需要从使用构建输出过渡到运行一个构建。它们首先需要成为开发者,而如果很难学会如何构建一个项目,这就成为了最终用户花时间为项目做贡献的妨碍因素。在广泛可移植项目中,最终用户不需要遵循一组神秘的构建指令来开始成为开发者。他们可以签出源码,修改源码,构建,然后提交贡献,这个过程不需要问谁要求帮助建立构建环境。当为开源项目贡献源码的成本更低的时候,你就会看到源码贡献的增长,特别是一些不经意的贡献可能对项目的成功和项目的失败造成很大的影响。在一组广泛的开源项目中使用Maven的一个附加作用就是它使得开发者为不同的开源项目贡献源码变得更加容易。