包含内容
- maven属性
- 构建环境的差异
- 资源过滤
- Maven Profile
- Web资源过滤
- 在profile中激活集成测试
- 小结
前言
- 灵活构建:
- 项目都会有开发环境、测试环境和产品环境,这些环境的数据库库配置不尽相同,那么项目构建的时候就需要能够识别所在环境并使用正确的配置。
- 项目开发了大量的集成测试,这些测试运行起来非常耗时,不适合在每次构建项目时都运行,因此需要一些手段能让我们在特定的时候才激活这些集成测试。
- maven如何实现灵活构建,内置了三大特性:
- 属性
- Profile
- 资源过滤
1.Maven属性
- maven中有6类属性:
- 内置属性
- POM属性
- 自定义属性
- Settings属性
- Java系统属性
- 环境变量属性
1.1 内置属性
- 主要有两个常用内置属性
${basedir}表示项目根目录,即包含pom.xml文件的目录
${version}表示项目版本
1.2 POM属性
- 用户可以使用该类属性引用POM文件中对应元素的值。例如${project.artifactId}就对应了<project><artifactId>元素的值.
- 常用的POM属性包括:
${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/。
${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/。
${project.build.directory}:项目构建输出目录,默认为target/。
${project.outputDirectory}:项目的主代码编译输出目录,默认为target/classes/。
${project.testOutputDirectory}:项目测试代码编译输出目录,默认为target/test-classes/。
${project.groupId}:项目的groupId。
${project.artifactId}:项目的artifactId。
${project.version}:项目的version。
${project.build.finalName}:项目打包输出文件的名称,默认为${project.artifactId}-${project.version}。
<jdk.version>1.6</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- 这些属性都对应了一个POM元素,它们中的一些属性的默认值是在超级POM中定义的。
1.3 自定义属性
- 用户可以在POM的<properties>元素下自定义Maven属性。例如:
<project>
...
<properties>
<my.prop>hello</my.prop>
</properties>
...
</project>
- 然后在POM中其他地方使用${my.prop}的时候会被替换成hello。
1.4 Settings属性
- 与POM属性同理,用户使用以settings.开头的属性引用settings.xml文件中XML元素的值,如常用的${settings.localRepository}指向用户本地仓库的地址。
1.5 Java系统属性
- 所有Java系统属性都可以使用Maven属性引用,例如${user.home}指向了用户目录。用户可以使用mvn help:system查看所有的Java系统属性。文章后面列出了查询的结果。
1.6 环境变量属性
- 所有环境变量都可以使用以env.开头的Maven属性引用。例如${env.JAVA_HOME}指代了JAVA_HOME环境变量的值。用户可以使用mvn help:system查看所有的Java系统属性。
使用范例
- 在一个多模块项目中,模块之间的依赖比较常见,这些模块通常会使用同样的groupId和version,这个时候就可以使用POM属性。
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>account-email</artifacId>
<version>${project.version}</version>
</denpendency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>account-persist</artifacId>
<version>${project.version}</version>
</denpendency>
</dependencies>
- 在配置插件的时候,同样可以使用Maven属性来方便地自定义插件行为。如:maven-surefire-plugin插件运行后默认的测试报告目录为target/surefire-reports,这实际上就是${project.build.directory}/surefire-reports,查询该插件文档,发现该插件提供了reportsDirectory参数来配置测试报告目录。因此如果想要改变测试报告目录,如改成target/test-reports,就可以使用下面代码:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<skip>false</skip> <!-- 不跳过执行测试代码 -->
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
</configuration>
</plugin>
2. 构建环境的差异
- 在不同的环境中,项目的源码应该使用不同的方式进行构建。
例如,我们在开发环境可能使用一套数据库配置。
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=dev
jdbc.password=dev-pwd
在线上环境可能使用另外一套数据库配置。
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://172.19.201.168:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=test
jdbc.password=test-pwd
- 相似的,对于缓存的配置、对于其他应用的RFC链接都可能在不同的生产环境下有不同的配置。
- 那么对于不同环境的构建差异,要保证项目在不同的环境中都能正确的按照期望的来构建,作为一个构建 工具如何实现呢?
- 实现思路:针对开发、测试等不同环境定义多组参数,在系统的配置文件中通过参数进行引用。在项目构建时对这些配置文件进行拦截,将参数使用值进行替换,但是因为对不同环境配置了多组参数,究竟使用哪一组进行替换需要通过一定的方式(命令行、settings文件、系统属性等)来指明。这样就可以实现不同环境进行特定的构建。
- 为此需要做的事情大概涉及一下几件事:1.为不同环境定义多组属性。2.在系统资源文件中使用属性名称来配置,后期替换成真正需要的值。3.通过一种方式指明构建项目时使用哪一组属性。4.对系统中使用属性名称进行配置的资源文件进行拦截,并将资源文件中的属性名称使用定义的属性值进行替换。
- 下面通过灵活配置数据库信息进行具体说明。
3.资源过滤
3.1需求案例
- 对于数据库的配置来说,我们一般会在src/main/resources目录下添加数据库的配置文件jdbc.properties文件。连接数据库使用的驱动类、URL、用户名和密码都可能发生变化,因此用Maven属性取代它们。
3.2实现步骤
3.2.1. 在 jdbc.properties文件中使用属性
jdbc.driverClass=${db.driver}
jdbc.jdbcUrl=${db.url}
jdbc.user=${db.username}
jdbc.password=${db.username}
- 这里使用了4个Maven属性,db.driver、db.url等,它们的命名是任意的,视情况而选择合适名称。
3.2.2.在POM中定义profile定义属性
既然使用了Maven属性,我们就需要在某个地方定义他们,前面介绍了自定义maven属性,而上面这些属性主要为了适应不同开发环境,所以maven提供了profile可以对不同属性进行分类。在这里我们需要用到profile将其包裹起来,而且profile定义在POM中。
<project>
<profiles>
<profile>
<id>dev</id>
<properties>
<db.driver>com.mysql.jdbc.Driver</db.driver>
<db.url>jdbc:mysql://172.19.201.168:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8</db.url>
<db.username>dev</db.username>
<db.password>dev-pwd</db.password>
</properties>
</profile>
</profiles>
</project>
3.3.3 配置maven-resources-plugin插件开启资源过滤
- 有了属性定义,配置文件中也使用了这些属性,但是这些属性目前只能在POM中使用,如在POM使用{db.username}。因此要让Maven解析资源文件中的Maven属性。
- 资源文件的处理其实是maven-resources-plugin做的事情,它默认的行为只是将项目主资源文件复制到主代码编译输出目录中(target/classes),将测试资源文件复制到测试代码编译输出目录中,要让该插件能够解析资源文件中的Maven属性,就需要开启资源过滤,被过滤的文件Maven就会将其中的Maven属性替换成对应的值。
- 为主资源目录和测试资源目录开启过滤。
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<testResource>
<directory>${basedir}/src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
3.3.4 激活profile
一切准备就绪,最后只要在命令行激活profile,maven就能够在构建项目的时候使用profile中属性值替换数据库配置文件中的属性引用。
命令:
mvn clean install -Pdev
-P参数表示在命令行激活一个profile。这里激活了id为dev的profile(多个id之间以逗号分隔)。构建完成后,输出目录中的数据库配置就是开发环境的配置了:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=dev
jdbc.password=dev-pwd
下一节内容
Maven Profile:profile更多的激活方式、不同的种类(不仅仅只有pom.xml可以定义哦,定义位置不同作用范围也不一样)、profile中可使用的元素等。
Web资源过滤:除了一般资源文件(src/main/resources)外,web还有包括了一种web资源文件(src/main/webapp),对于web资源文件的过滤又是怎么的呢?(首先处理web资源文件的插件不是maven-resources-plugin,所以配置resources时没用的。)
在profile中激活集成测试:一个项目中会有单元测试也会有集成测试,单元测试运行快,因此构建项目就快,集成测试运行比较耗时,所以如果不想每次构建都运行集成测试该怎么办呢?
- 通过mvn help:system查看的java系统属性(其中系统环境变量没有显示粘贴出来)
===============================================================================
========================= Platform Properties Details =========================
===============================================================================
===============================================================================
System Properties
===============================================================================
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=D:\Soft\Java\jdk1.8.0_65\jre\bin
java.vm.version=25.65-b01
maven.multiModuleProjectDirectory=C:\Users\dell
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
guice.disable.misplaced.annotation.check=true
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.country=CN
user.script=
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=Service Pack 1
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\dell
java.runtime.version=1.8.0_65-b17
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=D:\Soft\Java\jdk1.8.0_65\jre\lib\endorsed
os.arch=amd64
java.io.tmpdir=C:\Users\dell\AppData\Local\Temp\
line.separator=
java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 7
classworlds.conf=D:\Soft\maven\apache-maven-3.3.3\bin\m2.conf
sun.jnu.encoding=GBK
java.library.path=D:\Soft\Java\jdk1.8.0_65\bin;C:\Windows\Sun\Java\bin;C:\Window
s\system32;C:\Windows;D:\Soft\Spring-Boot-CLI\bin;D:\Soft\nexus-3.1.0-04-win64\n
exus-3.1.0-04\bin;D:\Soft\maven\apache-maven-3.3.3\bin;D:\Soft\Java\jdk1.8.0_65\
bin;D:\Soft\Java\jdk1.8.0_65\jre\bin;C:\ProgramData\Oracle\Java\javapath;C:\Prog
ram Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Window
s\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerS
hell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Fil
es\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(
R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Manage
ment Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engi
ne Components\IPT;D:\Soft\VanDyke Software\Clients\;D:\Soft\git\Git\bin;D:\Soft\
mysql\installationpath\MySQL Server 5.5\bin;.
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.1
user.home=C:\Users\dell
user.timezone=Asia/Shanghai
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=GBK
java.specification.version=1.8
java.class.path=D:\Soft\maven\apache-maven-3.3.3\boot\plexus-classworlds-2.5.2.j
ar
user.name=dell
java.vm.specification.version=1.8
sun.java.command=org.codehaus.plexus.classworlds.launcher.Launcher help:system
java.home=D:\Soft\Java\jdk1.8.0_65\jre
sun.arch.data.model=64
user.language=zh
java.specification.vendor=Oracle Corporation
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0_65
java.ext.dirs=D:\Soft\Java\jdk1.8.0_65\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path=D:\Soft\Java\jdk1.8.0_65\jre\lib\resources.jar;D:\Soft\Java\
jdk1.8.0_65\jre\lib\rt.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\sunrsasign.jar;D:\So
ft\Java\jdk1.8.0_65\jre\lib\jsse.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\jce.jar;D:
\Soft\Java\jdk1.8.0_65\jre\lib\charsets.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\jfr
.jar;D:\Soft\Java\jdk1.8.0_65\jre\classes
java.vendor=Oracle Corporation
sun.stderr.encoding=ms936
maven.home=D:\Soft\maven\apache-maven-3.3.3
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding=UnicodeLittle
sun.cpu.endian=little
sun.stdout.encoding=ms936
sun.desktop=windows
sun.cpu.isalist=amd64
参考文章:Maven学习笔记(十一):灵活的构建