文档章节

Maven实战读书笔记(15)

祥林会跟你远走高飞
 祥林会跟你远走高飞
发布于 2014/12/24 18:14
字数 3451
阅读 368
收藏 13

关于灵活的构建

一个优秀的构建系统必须足够灵活,它应该能够让项目在不同的环境下都能成功地构建。

例如,典型的项目都会有开发环境、测试环境和产品环境,这些环境的数据库配置不尽相同,那么项目构建的时候就需要能够识别所在的环境并使用正确的配置

还有一种常见的情况是,项目开发了大量的集成测试,这些测试运行起来非常耗时,不适合在每次构建项目的时候都运行,因此需要一种手段能让我们在特定的时候才激活这些集成测试,Maven为了支持构建的灵活性,内置了三大特性,即属性、Profile和资源过滤

 

Maven属性

使用Maven属性归类依赖

       <properties>

              <springframework.version>2.5.6</springframework.version>

       </properties>

 

       <dependencies>

              <dependency>

                     <groupId>org.springframework</groupId>

                     <artifactId>spring-core</artifactId>

                     <version>${springframework.version}</version>

              </dependency>

              <dependency>

                     <groupId>org.springframework</groupId>

                     <artifactId>spring-beans</artifactId>

                     <version>${springframework.version}</version>

              </dependency>

              ...

       </dependencies>

这可能是最常见的使用Maven属性的方式,通过<properties>元素用户可以自定义一个或多个Maven属性,然后再POM的其他地方使用${属性名称}的方式引用该属性,这种做法的最大意义在于消除重复

 

Maven6类属性

1内置属性,主要有两个常用内置属性——${basedir} 表示项目根目录,即包含pom.xml文件的目录;${version} 表示项目版本

2POM属性,用户可以使用该类属性引用POM文件中对应元素的值,例如:

${project.artifactId}就对应了<project> <artifactId>元素的值,常用的POM属性包括:

n     ${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/

n     ${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/

n     ${project.build.directory}:项目构建输出目录,默认为target/

n     ${project.outputDirectory}:项目主代码编译输出目录,默认为target/classes/

n     ${project.testOutputDirectory}:项目测试代码编译输出目录,默认为target/testclasses/

n     ${project.groupId}:项目的groupId

n     ${project.artifactId}:项目的artifactId

n     ${project.version}:项目的version,与${version}等价

n     ${project.build.finalName}:项目打包输出文件的名称,默认为${project.artifactId}-

     ${project.version}

这些属性都对应了一个POM元素,它们中一些属性的默认值都是在超级POM中定义的

3自定义属性,用户可以在POM<properties>元素下自定义Maven属性

       <project>

       ...

              <properties>

                     <my.prop>hello</my.prop>

              </properties>

       ...

       </project>

       然后在POM中其他地方使用${my.prop}的时候会被替换成hello

4Settings属性,与POM属性同理,用户使用以settings.开头的属性引用settings.xml文件中xml元素的值,如常用的${settings.localRepository}指向用户本地仓库的地址

5Java系统属性,所有Java系统属性都可以使用Maven属性引用,例如${user.home}指向了用户目录,用户可以使用mvn help:system查看所有的Java系统属性

6环境变量属性,所有环境变量都可以使用以env.开头的Maven属性引用。例如${env.JAVA_HOME}指代了JAVA_HOME环境变量的值。用户可以使用mvn help:system查看所有的环境变量

 

使用POM属性配置依赖

<dependencies>

       <dependency>

              <groupId>${project.groupId}</groupId>

              <artifactId>account-email</artifactId>

              <version>${project.version}</version>

       </dependency>

       <dependency>

              <groupId>${project.groupId}</groupId>

              <artifactId>account-persist</artifactId>

              <version>${project.version}</version>

       </dependency>

</dependencies>

 

使用Maven属性配置插件

修改测试报告目录

<plugin>

       <groupId>org.apache.maven.plugins</groupId>

       <artifactId>maven-surefire-plugin</artifactId>

       <version>2.5</version>

       <configuration>

              <reportsDirectory>

                     ${project.build.directory}/test-reports

              </reportsDirectory>

       </configuration>

</plugin>

 

构建环境的差异,考虑一下这种情况

在不同的环境中,项目的源码应该使用不同的方式进行构建,最常见的就是数据库配置了

例如在开发的过程中,有些项目会在src/main/resources/目录下放置带有如下内容的数据库配置文件:

database.jdbc.driverClass=com.mysql.jdbc.Driver

database.jdbc.connectionURL=jdbc:mysql://localhost:3306/test

database.jdbc.username=dev

database.jdbc.password=dev-pwd

这本没什么问题,可当测试人员想要构建项目产品并进行测试的时候,他们往往需要使用不同的数据库,这时的数据库配置文件可能是这样的:

database.jdbc.driverClass=com.mysql.jdbc.Driver

database.jdbc.connectionURL=jdbc:mysql://10.1.0.56:3306/test

database.jdbc.username=test

database.jdbc.password=test-pwd

连接数据库的URL、用户名和密码都发生了变化,类似地,当项目被发布到产品环境的时候,所使用的数据库配置又是另外一套了。这个时候,比较原始的做法是,使用与开发环境一样的构建,然后再测试或者发布产品之前再手动更改这些配置。这是可行的,也是比较常见的,但肯定不是最好的方法。本书已经不止一次强调,手动往往就意味着低效和错误,因此需要找到一种方法,使它能够自动对构建环境的差异

Maven的答案是针对不同的环境生成不同的构件。也就是说,在构建项目的过程中,Maven就已经将这种差异处理好了

 

资源过滤

为了应对环境的变化,首先需要使用Maven属性将这些将会发生变化的部分提取出来。

将上面的配置,用Maven属性取代

database.jdbc.driverClass=${db.driver}

database.jdbc.connectionURL=${db.url}

database.jdbc.username=${db.username}

database.jdbc.password=${db.password}

这里定义了4Maven属性:db.driverdb.urldb.usernamedb.password

 

使用一个额外的profile包裹自定义Maven属性

针对开发环境的数据库配置

<profiles>

       <profile>

              <id>dev</id>

              <properties>

                     <db.driver> com.mysql.jdbc.Driver </db.driver>

                     <db.url> jdbc:mysql://localhost:3306/test </db.url>

                     <db.username> dev </db.username>

                     <db.password> dev-pwd </db.password>

              </properties>

       </profile>

</profiles>

对上面这些配置进行解释

Maven属性定义与直接在POMproperties元素下定义没什么区别,只是使用了一个iddevprofile,其目的是将开发环境下的配置与其他环境区分开

 

那么,有了属性定义,配置文件中也使用了这些属性,一切OK了吗?

还是不行,Maven属性默认只有在POM中才会被解析。也就是说,${db.username}放到POM中会变成test,但是如果放到src/main/resources目录下的文件中,构建的时候它将仍然还是${db.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>

为测试资源目录开启过滤

<resources>

       <resource>

              <directory>${project.basedir}/src/test/resources</directory>
              <filtering>true</filtering>

       </resource>

</resources>

 

配置多个资源目录

<resources>

       <resource>

              <directory>src/main/resources</directory>
              <filtering>true</filtering>

       </resource>

</resources>

<resources>

       <resource>

              <directory>src/main/sql</directory>
              <filtering>false</filtering>

       </resource>

</resources>

其中src/main/resources开启了过滤,而src/main/sql没有启用过滤

 

执行mvn clean install -Pdev命令

mvn-P参数表示在命令行激活一个profile,这里激活了iddevprofile。构建完成后,输出目录中的数据库配置就是开发环境的配置了

 

 

为了构建差异的jdbc配置,我们做了哪些配置?

1、数据库配置的变化部分提取成了Maven属性

2、在POMprofile中定义了这些属性的值

3、为资源目录开启了属性过滤

4、最后需要在命令行激活profileMaven就能够在构建项目的时候使用profile中属性值替换数据库配置文件中的属性引用

 

激活profileMaven支持很多种激活Profile的方式

1、命令行激活

使用mvn命令行参数-P加上profileid来激活profile,多个id之间以逗号分隔

使用命令激活dev-xdev-y两个profile

mvn clean install -Pdev-x,dev-y

2settings文件显式激活

如果用户希望某个profile默认一直处于激活状态,就可以配置settings.xml文件的activeProfiles元素,表示其配置的profile对于所有项目都处于激活状态

settings文件显式激活profile

<settings>

...

       <activeProfiles>

              <activeProfile>dev-x</activeProfile>

       </activeProfiles>

...

</settings>

3、系统属性激活

配置当某系统属性存在的时候,自动激活profile

当系统属性test存在时,激活此profile

<profiles>

       <profile>

              <activation>

                     <property>

                            <name>test</name>

                     </propety>

              </activation>

              ...

       </profile>

</profiles>

当系统属性test存在,且值等于x的时候激活profile

<profiles>

       <profile>

              <activation>

                     <property>

                            <name>test</name>

                            <value>x</value>

                     </propety>

              </activation>

              ...

       </profile>

</profiles>

上面的配置,不要忘了在命令行声明系统属性

mvn clean install -Dtest=x

因此,这其实也是一种从命令行激活profile的方法,而且多个profile完全可以使用同一个系统属性来激活

4、操作系统环境激活

Profile还可以自动根据操作系统环境激活,如果构建在不同的操作系统有差异,用户完全可以将这些差异写进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的值包括WindowsUNIXMac等,而其他几项namearchversion,用户可以通过查看环境中的系统属性os.nameos.archos.version获得

5、文件存在与否激活

Maven能够根据项目中某个文件存在与否来决定是否激活profile

基于文件存在与否激活profile

<profiles>

       <profile>

              <activation>

                     <file>

                            <missing>x.properties</missing>

                            <exists>y.properties</ exists >

                     </file>

              </activation>

              ...

       </profile>

</profiles>

6、默认激活

用户可以在定义profile的时候指定其默认激活

默认激活profile

<profiles>

       <profile>

              <id>dev</id>

              <activation>

                     <activeByDefault>true</activeByDefault>

              </activation>

              ...

       </profile>

</profiles>

使用activeByDefault元素用户可以指定profile自动激活,不过需要注意的是,如果POM中有任何一个profile通过以上其他任意一种方式被激活了,所有的默认激活配置都会失效

 

项目中有很多profile,用户怎么知道哪个激活了?

maven-help-plugin提供一个目标帮助用户了解当前激活的profile

mvn help:active-profiles

maven-help-plugin还有另外一个目标用来列出当前所有的profile

mvn help:all-profiles

 

那么,profile的种类有哪些?或者说在哪里可以配置profile

1pom.xml,很显然,pom.xml中声明的profile值对当前项目有效

2、用户settings.xml:用户目录下.m2/settings.xml中的profile对本机上该用户所有的Maven项目有效

3、全局settings.xmlMaven安装目录下conf/settings.xml中的profile对本机上所有的Maven项目有效

4profiles.xmlMaven 2):还可以在项目根目录下使用一个额外的profiles.xml文件来声明profile,不过该特性已经在Maven 3中被移除。建议用户将这类profile移到settings.xml

 

POM中的profile可使用的元素

因为profile可以伴随pom.xml一起存在,所以可以使用很多POM元素

<project>

       <repositories></repositories>

       <pluginRepositories></pluginRepositories>

       <distributationManagement></distributationManagement>

       <dependencyManagement></dependencyManagement>

       <modules></modules>

       <properties></properties>

       <reporting></reporting>

       <build>

              <plugins></plugins>

              <defaultGoal></defaultGoal>

              <resources></resources>

              <testResources></testResources>

              <finalName></finalName>

       </build>

</project>

 

POM外部的profile可使用的元素

由于无法保证外部的profile随着特定的pom.xml一起分发,所以外部的profile可使用的元素很少

<project>

       <repositories></respositories>

       <pluginRepositories></pluginRepositories>

       <properties></properties>

</project>

外部的profile仅仅能影响项目的仓库和Maven属性

 

Web资源过滤

Web项目中,资源文件同样位于src/main/resources目录下,它们经处理后会位于WAR包的WEB-INF/classes目录下,这也是Java代码编译打包后的目录。也就是说,这类资源文件在打包过后位于应用程序的classpath中。

Web项目中海油另外一类资源文件,默认它们的源码位置src/main/webapp/目录,经打包后位于WAR包的根目录。

例如,一个Web项目的css源码文件在src/main/webapp/css/目录,项目打包后可以在WAR包的css/目录下找到对应的css文件。这一类资源文件称作web资源文件,它们在打包过后不位于应用程序的classpath

与一般的资源文件一样,web资源文件默认不会被过滤。开启一般资源文件的过滤也不会影响到web资源文件

不过有的时候,我们可能希望在构建项目的时候,为不同的客户使用不一样的资源文件(例如客户的logo图片不同,或者css主题不同)。这时可以在web资源文件中使用Maven属性,例如用 ${client.logo}表示客户的logo图片,用${client.theme}表示客户的css主题。然后使用profile分别定义这些Maven属性的值

 

针对不同客户web资源的profile

<profiles>

       <profile>

              <id>client-a</id>

              <properties>

                     <client.logo>a.jpg</client.logo>

                     <client.theme>red</client.theme>

              </properties>

       </profile>

       <profile>

              <id>client-b</id>

              <properties>

                     <client.logo>b.jpg</client.logo>

                     <client.theme>blue</client.theme>

              </properties>

       </profile>

</profiles>

 

web资源目录src/main/webapp/开启过滤

<plugin>

       <groupId>org.apache.maven.plugins</groupId>

       <artifactId>maven-war-plugin</artifactId>

       <version>2.1-beta-1</version>

       <configuration>

              <resource>

                     <filtering>true</filtering>

                     <directory>src/main/webapp</directory>

                     <includes>

                            <include>**/*.css</include>

                            <include>**/*.js</include>

                     </includes>

              </resource>

       </configuration>

</plugin>

对上述配置进行解释

1web资源目录src/main/webapp(这也是默认的web资源目录)

2、配置filtering开启过滤,并且使用includes指定要过滤的文件,这里是所有的cssjs文件

3、激活某个profile进行构建,mvn clean install -Pclient-a,告诉web资源文件使用logo图片a.jpg,使用css主题red

 

profile中激活集成测试?

 

什么是集成测试?

 

如何在Maven中使用TestNG


© 著作权归作者所有

祥林会跟你远走高飞
粉丝 27
博文 50
码字总数 98029
作品 0
昌平
程序员
私信 提问
Maven实战读书笔记(17)

Eclipse 1、eclipse是非常流行的IDE,为了方便用户,日常开发使用的各种工具都会提供相应的Eclipse插件 2、Eclipse默认就集成了JUnit单元测试框架、CVS版本控制工具以及Mylyn任务管理框架 3、...

祥林会跟你远走高飞
2014/12/25
0
0
Maven实战读书笔记(16)

Maven聚合项目信息 1、Maven不仅仅是一个自动化构建工具和一个依赖管理工具,它还能够帮助聚合项目信息,促进团队间的交流 2、POM可以包含各种项目信息,如项目描述、版本控制系统地址、缺陷...

祥林会跟你远走高飞
2014/12/25
0
0
Maven实战读书笔记(10)

account-captcha的POM配置 <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......

祥林会跟你远走高飞
2014/12/17
0
0
Maven实战读书笔记(18)

编写Maven插件的一般步骤 1、创建一个maven-plugin项目:插件本身也是Maven项目,特殊的地方在于它的packaging必须是maven-plugin,用户可以使用maven-archetype-plugin快速创建一个Maven插件...

祥林会跟你远走高飞
2014/12/25
0
0
《Linux内核设计与实现》读书笔记 - 目录 (完结)

《Linux内核设计与实现》读书笔记 - 目录 (完结) 读完这本书回过头才发现, 第一篇笔记居然是 2012年8月发的, 将近一年半的时间才看完这本书(汗!!!). 为了方便以后查看, 做个《Linux内核设计...

你的猫大哥
2018/01/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android Camera模块解析之拍照

最近学习Android的camera模块,本文先介绍一下camera2的api,然后给出android camera拍照的例子,讲解一下camera 拍照的原因知识,与大家共勉。 camera2 介绍 android camera拍照功能介绍 一...

天王盖地虎626
21分钟前
5
0
Excel 曝Power Query安全漏洞

近日,Mimecast 威胁中心的安全研究人员,发现了微软 Excel 电子表格应用程序的一个新漏洞,获致 1.2 亿用户易受网络攻击。其指出,该安全漏洞意味着攻击者可以利用 Excel 的 Power Query 查...

linuxCool
27分钟前
1
0
SpringBoot | 第三十八章:基于RabbitMQ实现消息延迟队列方案

前言 >前段时间在编写通用的消息通知服务时,由于需要实现类似通知失败时,需要延后几分钟再次进行发送,进行多次尝试后,进入定时发送机制。此机制,在原先对接银联支付时,银联的异步通知也...

oKong
27分钟前
6
0
Excel 曝Power Query安全漏洞

近日,Mimecast 威胁中心的安全研究人员,发现了微软 Excel 电子表格应用程序的一个新漏洞,获致 1.2 亿用户易受网络攻击。其指出,该安全漏洞意味着攻击者可以利用 Excel 的 Power Query 查...

linux-tao
44分钟前
1
0
Java - NIO框架

Java NIO提供了与标准IO不同的IO工作方式。 Channels and Buffers(通道和缓冲区) 标准IO基于字节流和字符流,NIO基于通道(Channel)和缓冲区(Buffer)。数据从channel读取到buffer,或从Buffe...

丰田破产标志
47分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部