maven---灵活构建(一)

作者: zlcook | 来源:发表于2017-04-04 18:01 被阅读197次

    包含内容

    • 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}构建时其值会变成dev,但是如果放到src/main/resources/目录下的文件中,如jdbc.properties中,构建时仍然是${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学习笔记(十一):灵活的构建

    相关文章

      网友评论

        本文标题:maven---灵活构建(一)

        本文链接:https://www.haomeiwen.com/subject/lnhfottx.html