`

maven日记(十):灵活的构建

阅读更多

问题1:典型的项目都会有开发环境、测试环境、生产环境,这些环境的配置不同,怎样在构建的时候识别这些环境并使用正确的配置

问题2:有些集成测试运行起来非常耗时,不适合每次构建都运行,需要一种手段在特定时候才运行这些集成测试

maven为了解决上面的难题,提供了三大特性,即:属性、Profile、资源过滤

>> maven属性:

通过定义<properties><spring.version>3.1.1</spring.version></properties>,这个是最常见的属性方式。

这不是maven属性的全部,事实上这只是maven6类属性中的一类而已。这6类属性分别为:

* 内置属性:主要有两个常见内置属性—${basedir}表示项目根目录,也就是pom.xml的文件所在目录;${version}表示项目版本

* pom属性:pom文件中对应元素的值。例如${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,与${version}等价

  > ${project.buld.finalName}:项目打包输出文件的名字,默认为${project.artifactId}-${project.version}

* 自定义属性:这个就是最常见的properties><spring.version>3.1.1</spring.version></properties>这种形式

* Settings属性:

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

* Java系统属性:

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

* 环境变量属性:

所有环境变量都可以使用以env.开头的maven属性引用,例如${env.JAVA_HOME}指向了JAVA_HOME目录。

>> 资源过滤:

为了应对环境变化,开发、测试、生成环境配置不一样。一般来讲数据库的配置是不一样的,于是我们把这些配置写到properties文件中:

database.jdbc.driverClass=${db.driver}
database.jdbc.url=${db.url}
database.jdbc.username=${db.username}
database.jdbc.password=${db.password}

现在需要使用一个额外的profile将其包裹:

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>....</db.url>
            <db.username>dev_user</db.username>
            <db.password>dev_password</db.password>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>....</db.url>
            <db.username>test_user</db.username>
            <db.password>test_password</db.password>
        </properties>
    </profile>
</profiles>

资源文件的处理其实就是maven-resources-plugin做的事情,它默认的行为是将项目主资源文件复制到主代码编译输出目录中,将测试资源文件复制到测试代码编译输出目录中。不过只有一些简单的pom配置,该插件就能解析资源文件中的maven属性,开启资源过滤。

为主资源目录开启过滤:

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

为测试资源目录开启过滤:

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

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

# mvn clean install -Pdev

构建完后,输出目录中的数据库配置就是开放环境的配置了。

>> Maven Profile:

从上面可以看出,不同环境下构建很可能是不一样的,典型情况就是数据库配置。另外,有些环境可能还需要配置插件使用本地文件,或使用特殊版本的依赖,或需要一个特殊构件的名称。为了让构建在各个环境下方便移植,maven引入了profile概念。

profile能够在构建的时候修改pom的一个子集,或者添加额外的配置元素,用户可以使用多种方式激活profile,实现不同环境下构建移植。

上面已经很清楚了,# mvn clean install -Pdev激活dev profile,而# mvn clean install -Ptest激活test profile

– 激活profile的方式:

1,命令行激活:

就是上面的# mvn clean install -Pdev激活dev profile,而# mvn clean install -Ptest激活test profile

2,settings文件显示激活:

如果希望某个profile默认一直处于激活状态,可以配置M2_HOME/settings.xml文件的activeProfiles元素:

 

<settings>
    ...
    <activeProfiles>
        <activeProfile>dev</activeProfile>
    </activeProfiles>
    ...
</settings>

 

3,系统属性激活:

用户可以配置当某个系统属性存在的时候自动激活profile:

<profiles>    
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>....</db.url>
            <db.username>dev_user</db.username>
            <db.password>dev_password</db.password>
        </properties>
        <activation>
            <property>
                <name>dev</name>
                <value>true</value>
            </property>
        </activation>
    </profile>
</profiles>

用户可以在命令行声明系统属性,例如:

# mvn clean install -Ddev=true 这样就可以激活上面的dev profile

4,操作系统环境变量激活:

profile还可以自动根据操作系统环境激活:

<profiles>    
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>....</db.url>
            <db.username>dev_user</db.username>
            <db.password>dev_password</db.password>
        </properties>
        <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,基于文件是否存在激活:

<profiles>    
    <profile>
        ...
        <activation>
            <file>
                <missing>dev.properties</missing>
                <exists>test.properties</exists>
            </file>
        </activation>
    </profile>
</profiles>

6,默认就激活:

<profiles>    
    <profile>
        ...
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
</profiles>

如果项目中有很多profile,通过下列命令去查看各个profile的激活情况:

# mvn help:active-profiles

# mvn help:all-profiles

— profile的作用范围:

* pom.xml:对当前项目有效

* ${user.home}/.m2/settings.xml,对该用户有效

* ${M2_HOME}/conf/settings.xml,对全局有效

一般不建议在全局settings中添加profile

>> 在profile中激活集成测试

现在的需求是每次构建的时候只运行所有的单元测试,因为这不会消耗太多的时间,然后以一个相对低一点的频率执行所有的集成测试,例如每隔两天才执行一次。

TestNG中的组的概率能够很好的支持单元测试和集成测试的分类标记。

@Test(groups={"unit"})标注一个测试方法属于单元测试,@Test(groups={"integration"})标注一个测试方法属于集成测试,然后:

<project>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <groups>unit</groups>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>full-test</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <version>2.5</version>
                        <configuration>
                            <groups>unit</groups>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

有了上述配置,用户就可以根据实际情况配置持续集成服务器,两个任务,一个定时check源码,然后默认构建,只执行单元测试。另一个任务两天扫描一次,执行全测试。

 

本人博客已搬家,新地址为:http://yidao620c.github.io/

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics