11 Maven 灵活的构建
Maven 灵活的构建
一个优秀的构建系统必须足够灵活,它应该能够让项目在不同的环境下都能成功地构建。例如,典型的项目都会有开发环境、测试环境和产品环境,这些环境的数据库配置不尽相同,那么项目构建的时侯就需要能够识别所在的环境并使用正确的配置。还有一种常见的情况是,项目目开发了大量的集成测试,这些测试运行起来非常耗时,不适合在每次构建项目的时候都运行,因此需要一种手段能让我们在特定的时候才激活这些集成测试。Maven 为了支持构建的灵活性,内置了三大特性,即属性、 Profile 和资源过滤。本章介绍如何合理使用这些特性来帮助项目自如地应对各种环境。
1. Maven 属性
前面的章节已经简单介绍过 Maven 属性的使用:
<properties>
<spring.version>4.1.9</spring.version>
</properties>
这可能是最常见的使用 Maven 属性的方式,通通过 properties 元素用户可以自定义个或多个 Maven 属性,然后在 POM 的其他地方使用用S属性名称}的方式引用该属性,这种做法的最大意义在于消除重复。事实上这只是 6 类 Maven 属性中的一类而已。这 6 类属性分别为:
内置属性 :主要有两两个常用属性。${basedir} 表示项目根目录,即包含 pom.xml 文件的目录; ${version} 表示项目版本
POM属性 :用户可以使用该类属性引用 POM 对应元素的值。例如 ${project.artifactId} 对应 artifactId 元素的值,常用的 POM 属性包括:
- ${project.build.sourceDirectory}:项目的主源码目录,默认为 src/main/java/
- ${project.build.testSoureedirectory}:项目目的测试源码目录,默认为 src/test/java/
- ${project.build.directory}:项目构建输出目录,默认为 target/
- ${project.outputDirectory}:项目主代码编译输出目录,默认为 target/classes/
- ${project.testoutputDirectory}:项目测试代码编译输出目录,默认为 targel/test-classes/
- ${project.groupld}:项目的 groupId
- ${project.artifactId}:项目的 artifactId
- ${project.version}:项目的 version,与 ${version} 等价
- ${project.build.fileName}:项目打包输出文件的名称,默认为 ${project.groupld}-${project.artifactId}
这些属性都对应了一个 POM 元素,它们中一些属性的默认值都是在超级 POM 中定义的。
自定义属性 :用户可以在 POM 的 properties 元素下自定义 Maven 属性。
Settings属性 :与 POM 属性同理,用户使用以 settngs. 开头的属性引用 settings.xml 文件中 XML 元素的值,如常用的 ${settings.localRepository} 指向用户本地仓库的地址。
Java系统属性 :所有 Java 系统属性都可以使用 Maven 属性引用,例例如 ${user.home} 指向了用户目录。用户可以使用用 mvn help:system 查看所有的 Java 系统属性。
环境变量属性 :所有环境变量都可以使用以 env. 开头的 Maven 属性引用。例如 ${env.JAVA_HOME} 指代了 JAVA_HOME 环境变量的值。用户可以使用 mvn help:system 查看所有的环境变量。
2. 资源过滤
为了应对环境的变化,首先需要使用 Maven 属性将这些将会发生变化的部分提取出来,用 Maven 属性取代它们
jdbc.dirver=${jdbc.dirver}
jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}
这里定义了 4 个 Maven 属性:jdbc.driver、jdbc.url、jdbc.username 和 jdbc.password。既然使用了 Maven 属性,就应该在某个地方定义它们,这里要做的是使用一个额外的 profile 将其包裹,如代码如下:
<profiles>
<profile>
<id>dev</id>
<properties>
<jdbc.dirver>com.mysql.jdbc.Driver</jdbc.dirver>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/test</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>root</jdbc.password>
</properties>
</profile>
</profiles>
代码中的 Maven 属性定义与直接在 POM 的 properties 元素下定义并无二致,这里只是使用了一个 id 为 dev 的 profile,其目的是将开发环境下的配置与其他环境区别开来。
有了属性定义,配置文件中也使用了这些属性,一切 OK 了吗?还不行。读者要留意的是, Maven 属性默认只有在 POM 中才会被解析。也就是说,${username} 放到 POM 中会变成 test,但是如果放到 src/main/ resources/ 目录下的文件中,构建的时侯它将仍然还是 ${username}。因此,需要让 Maven 解析资源文件中的 Maven 属性。
资源文件的处理其实是 maven-resources-plugin 做的事情,它默认的行为只是将项目主资源文件复制到主代码编译输出目录中,将测试资源文件复制到测试代码编译输出目录中。不过只要通过一些简单的 POM 配置,该插件就能够解析资源文件中的 Maven 属性,即开启资源过滤。
Maven 默认的主资源目录和测试资源目录的定义是在超级 POM 中。要为资源目录开启过滤,只要在此基础上添加一行 filtering 配置即可。
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
到目前为止一切基本就绪了,我们将数据库配置的变化部分提取成了 Maven 属性,在 POM 的 profile 中定义了这些属性的值,并且为资源目录开启了属性过滤。最后,只需要在命令行激活 profile, Maven 就能够在构建项目的时候使用 profile 中属性值替换数据库配置文件中的属性引用。运行命令如下:
mvn clean install -Pdev
mvn 的-P 参数表示在命令行激活一个 profile。这里激活了 id 为 dev 的 profile。构建完成后,输出目录中的数据库配置就是开发环境的配置了:
jdbc.dirver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test
jdbc.username=root
jdbc.password=root
补充:Web 资源过滤:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-beta-1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>**/*.css</include>
<include>**/*.js</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
3. Maven Profile
为了能让构建在各个环境下方便地移植, Maven 引入了 profile 的概念。
3.1 针对不同环境的 profile
<profiles>
<profile>
<id>dev</id>
<properties>
<jdbc.dirver>com.mysql.jdbc.Driver</jdbc.dirver>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/dev</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>root</jdbc.password>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<jdbc.dirver>com.mysql.jdbc.Driver</jdbc.dirver>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/test</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>root</jdbc.password>
</properties>
</profile>
</profiles>
同样的属性在两个 profile 中的值是不一样的, dev profile 提供了开发环境数据库的配置,而 test profile 提供的是测试环境数据库的配置。
3.2 激活 profile
(1) 命令行激活
用户可以使用 mvn 命令行参数 -P 加上 profile 的 id来 激活 profile,多个 id 之间以逗号分隔。例如,下面的命令激活了 dev-x 和 dev-y 两个 profile
mvn c1ean install -Pdev-x,dev-y
(2) settings 文件显式激活
如果用户希望某个 profile 默认一直处于激活状态,就可以配置 settings.xml 文件的 activeProfiles 元素,表示其配置的 profile 对于所有项目都处于激活状态。
<settings>
<activeProfiles>
<activeProfile>dev-x</activeProfile>
</activeProfiles>
</settings>
(3) 系统属性激活
用户可以配置当某系统属性存在的时候,自动激活 profile。代码如下:
<profiles>
<profile>
<activation>
<name>test</name>
</activation>
</profile>
</profiles>
可以进一步配置当某系统属性 test 存在,且值等于 x 的时候激活 profile。代码如下:
<profiles>
<profile>
<activation>
<name>test</name>
<value>x</value>
</activation>
</profile>
</profiles>
不要忘了,用户可以在命令行声明系统属性。例如
mvn clean install -Dtest=x
因此,这其实也是一种从命令行激活 profile 的方法,而且多个 profile 完全可以使用同一个系统属性来激活。
(4) 操作系统环境激活 Profile
还可以自动根据操作系统环境激活,如果构建在不同的操作系统有差异,用户完全可以将这些差异写进 profile,然后配置它们自动基于操作系统环境激活。代码如下:
<profiles>
<profile>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
<!--...-->
</profile>
</profiles>
这里 family 的值包括 Windows、UNIX 和 Mac 等,而其他几项 name、arch、 version,用户可以通过查看环境中的系统属性 os.name、os.arch、os.version 获得。
(5) 文件存在与否激活
Maven 能够根据项目中某个文件存在与否来决定是否激活 profile。代码如下:
<profiles>
<profile>
<activation>
<file>
<missing>x.properties</missing>
<exists>y.properties</exists>
</file>
</activation>
...
</profile>
</profiles>
(6) 默认激活
用户可以在定义 profile 的时候指定其默认激活。代码如下:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
...
</profile>
</profiles>
使用 activeByDefault 元素用户可以指定 profile 自动激活。不过需要注意的是,如果 POM 中有任何一个 profile 通过以上其他任意一种方式被激活了,所有的默认激活配置都会失效。
如果项目中有很多的 profile,它们的激活方式各异,用户怎么知道哪些 profile 被激活了呢? maven-help-plugin 提供了一个目标帮助用户了解当前激活的 profiles:
mvn help:active-profiles
maven-help-plugin 还有另外一个目标用来列出当前所有的 profile:
mvn help:all-profiles
3.3 profile 的种类
根据具体的需要,可以在以下位置声明 profile:
- pom.xml : 很显然,pom.xml 中声明的 profile 只对当前项目有效。
- 用户 settings.xml : 用用户目录下.m2/ settings.xml 中的 profile 对本机上该用户所有的 Maven 项目有效。
- 全局 settings.xml : Maven 安装目录下 conf/settings.xml 中的 profile 对本机上所有的 Maven 项目有效。
11 Maven 灵活的构建的更多相关文章
- Maven学习总结(17)——深入理解maven灵活的构建
一个优秀的构建系统必须足够灵活,应该能够让项目在不同的环境下都能成功构建.maven为了支持构建的灵活性,内置了三大特性,即:属性.profile和资源过滤. 1.maven属性 maven属性分6类 ...
- 深入理解maven与应用(二):灵活的构建
深入理解maven及应用(一):生命周期和插件 參考官方url:http://maven.apache.org/guides/index.html 一个优秀的构建系统必须足够灵活,应该可以让项目在不同 ...
- 《Maven实战》第14章 灵活的构建
面对不同环境的差异能够灵活的构建项目, 操作系统的差异 开发环境.测试环境.产品环境的差异(最常用) 不同客户的差异 Maven中灵活的构建:属性.资源过滤.profile 14.1Maven属性 6 ...
- Maven实战读书笔记(六):Maven灵活构建
Maven为了支持构建的灵活性,内置了3大特性,即:属性.Profile和资源过滤. 6.1 Maven属性 Maven的属性与Java代码的常量有异曲同工之妙,都是为了消除重复,对相关内容进行统一管 ...
- SpringCloud核心教程 | 第二篇: 使用Intellij中的maven来快速构建Spring Cloud工程
spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选.分布式会话等等.它运行环 ...
- MAVEN学习-第一个Maven项目的构建
MAVEN安装成功之后就可以进行项目的构建和管理了: 为什么要用maven进行项目的构建和管理? 对于初学者来说一个最直接的也是最容易里的优点在于JAR包的管理,相对于以前开发一个项目的时候我们需要用 ...
- Maven实现项目构建直接部署Web项目到Tomcat
Maven实现项目构建直接部署Web项目到Tomcat配置如下: 1.Tomcat的用户及权限配置:在conf目录下,找到tomcat-users.xml,添加manager权限的用户. <ro ...
- Maven学习---使用maven进行项目构建
1. 使用maven进行项目构建 MyEclipse 自带maven 插件 Eclipse 需要单独安装maven插件 1.1. Maven 在企业中怎么用的 ? Maven : 项目构建工具 ,进行 ...
- jenkins+maven+Tomcat+shell构建自动化部署
https://yq.aliyun.com/articles/685931 1.官网下载war包:jenkins本质上就是一个web应用,直接下载jenkins的war包通过tomcat运行即可.ht ...
随机推荐
- Visual Studio自动添加头部注释
VS2013 自动添加头部注释 1.找到VS2013的安装目录 下文以安装目录 C:\Program Files (x86)\Microsoft Visual Studio 12.0 为例 2.修改C ...
- 关系型数据库之Mysql
简介 主要知识点包括:能够与mysql建立连接,创建数据库.表,分别从图形界面与脚本界面两个方面讲解 相关的知识点包括:E-R关系模型,数据库的3范式,mysql中数据字段的类型,字段约束 数据库的操 ...
- OpenACC Julia 图形
▶ 书上的代码,逐步优化绘制 Julia 图形的代码 ● 无并行优化(手动优化了变量等) #include <stdio.h> #include <stdlib.h> #inc ...
- angularJs按需加载代码(未验证)
一网友写的AngularJs按需加载代码,但未验证,放着备用. application.config( function($routeProvider) { ...
- 【转】Ultra simple ISO-7816 Interface
原文出自 http://hilbert-space.de/?p=135 While laying out a PCB for my SWP reader project I realized that ...
- FMX ScrollBox 拖拽控制
Firemonkey下的ScrollBox 拖拽控制,滚动控制,拖拽,滚动条 AniCalculations 仅允许纵向拖拽,拖拽 scrlbx.AniCalculations.TouchTracki ...
- mysql 1292-Truncated incorrect double value
sql = "select id from company where date_year_month = %s" % "2017-3" 出错 将%s改为'%s ...
- cobbler之ks文件编辑
kickstart文件的组成部分: 命令段:用于配置系统 软件包:指定要安装的程序包及程序包组 %packages 标识 @Base:使用@指定包组 lftp:直接写程序包名 注 ...
- Java Magic. Part 2: 0xCAFEBABE
Java Magic. Part 2: 0xCAFEBABE @(Base)[JDK, magic, 黑魔法] 转载请写明:原文地址 英文原文 系列文章: -Java Magic. Part 1: j ...
- ArcGIS模型构建器案例学习-批量删除空要素类地理模型
ArcGIS模型构建器案例学习笔记-批量删除空要素类地理模型 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:批量删除记录个数为0的矢量文件 优点:逻辑清晰,不 ...