Maven实战读书笔记(15)

关于灵活的构建css

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

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

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

 

Maven属性spring

使用Maven属性归类依赖sql

       <properties>数据库

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

       </properties>app

 

       <dependencies>webapp

              <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

相关文章
相关标签/搜索