Java知识积累一

maven多profile环境打包

-P参数

  1. P代表(Profiles配置文件)
  2. 可以通过-P进行传递或者赋值。
  3. pom.xml如下

     <profiles>
       <profile>
           <id>prod</id>
           ...
       </profile>
       <profile>
           <id>test</id>
           ...
       </profile>
     </profiles>
    
  4. 打包时执行mvn clean package -P test将触发test环境的profile配置

-D参数

  1. -D代表(Properties属性)
  2. pom.xml如下:

     <properties>
         <attr>defaultattr</attr>
     </properties>
    
  3. 执行mvn -Dattr=newattr clean package,则pom.xml内attr的实际值将被替换成newattr
  4. 命令行:mvn -DpropertyName=propertyValue clean package
    1. 如果propertyName不存在pom.xml,它将被设置。
    2. 如果propertyName已经存在pom.xml,其值将被作为参数传递的值覆盖-D。
    3. 如果要发送多个变量,请使用多个空格分隔符加-D:mvn -DpropA=valueA -DpropB=valueB -DpropC=valueC clean package

Properties Maven Plugin插件

  1. 官方网站:http://www.mojohaus.org/properties-maven-plugin/index.html
  2. 官网内容解析:

        
     If you have a properties file called teams.properties with this content:
     # 如果你有一个teams.properties文件,其中内容如下:
        
     toronto=raptors
     miami=heat
        
     and invoke the properties:read-project-properties goal, it would be the same as declaring the following in your pom.xml:
     # 而且使用 properties:read-project-properties goal ,它等价于在pom.xml文件中的下面声明:
        
     <properties>
         <toronto>raptors</toronto>
         <miami>heat</miami>
     </properties>
    
  3. 插件三大作用分析:
    1. 作用一:可以将*.properties属性文件和maven的pom.xml文件的属性互相转换;
    2. 作用二:可以设置系统属性;
    3. 作用三:可以收集Maven运行时的profile中定义的属性,将其写到文件中。

使用背景

  1. 通常把一些配置文件放到像src/main/resources/jdbc.properties这样的文件中。可是文件里咱们更多的放的仍是变量,内容以下:

     jdbc.driverClassName=${jdbc.driverClassName}
     jdbc.url=${jdbc.url}
     jdbc.username=${jdbc.username}
     jdbc.password=${jdbc.password}
     jdbc.validationQuery=${jdbc.validationQuery}
    
  2. 具体的值会放到pom.xml中,用<properties>来配置,以下所示代码:

     <?xml version="1.0" encoding="UTF-8"?>
     <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/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     	<modelVersion>4.0.0</modelVersion>
     	<groupId>com.qyf404</groupId>
        <artifactId>learn-maven</artifactId>
     	<version>1.0-SNAPSHOT</version>
     	<profiles></profiles>
     	<properties>
     		<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
     		<jdbc.url>jdbc:mysql://localhost/stock?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;autoReconnect=true</jdbc.url>
     		<jdbc.username>root</jdbc.username>
     		<jdbc.password></jdbc.password>
     		<jdbc.validationQuery>SELECT 1 + 1</jdbc.validationQuery>
     	</properties>
     	<build>
     		<resources>
     			<resource>
     				<filtering>true</filtering>
     				<directory>${project.basedir}/src/main/resources</directory>
     				<includes>
     					<include>*.properties</include>
     				</includes>
     			</resource>
     		</resources>
     	</build>
     </project>
    
  3. 按照上面的方式配置。执行mvn package后,在target/classes/jdbc.properties里能够看到配置文件被成功替换。
  4. 如果一个项目的配置的内容比较多,那么<properties>将有很多属性,那么是否可以将这些属性抽取到一个xx.properties文件中去呢?—properties-maven-plugin
  5. properties-maven-plugin能够在执行maven命令时,读取指定properties文件中的配置项,来实现和pom.xml中配置<properties>同样的效果。

基础使用(作用一)

  1. 根据上面的场景,在项目根目录下新建一个profiles/dev/my.properties 文件,内容如下:

     jdbc.driverClassName=com.mysql.jdbc.Driver
     jdbc.url=jdbc:mysql://localhost/stock?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;autoReconnect=true
     jdbc.username=root
     jdbc.password=
     jdbc.validationQuery=SELECT 1 + 1
    
  2. pom.xml中新增Properties Maven Plugin插件

     ...
     <!--<properties>-->
         <!--<jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>-->
         <!--<jdbc.url>jdbc:mysql://localhost/stock?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;autoReconnect=true</jdbc.url>-->
         <!--<jdbc.username>root</jdbc.username>-->
         <!--<jdbc.password></jdbc.password>-->
         <!--<jdbc.validationQuery>SELECT 1 + 1</jdbc.validationQuery>-->
     <!--</properties>-->
     <build>
         <resources>
             <resource>
                 <filtering>true</filtering>
                 <directory>${project.basedir}/src/main/resources</directory>
                 <includes>
                     <include>*.properties</include>
                 </includes>
             </resource>
         </resources>
         <plugins>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>properties-maven-plugin</artifactId>
                 <version>1.0-alpha-2</version>
                 <executions>
                     <execution>
                         <id>default-cli</id>
                         <phase>initialize</phase>
                         <!--注意设置-->
                         <goals>
                             <goal>read-project-properties</goal>
                         </goals>
                         <configuration>
                             <files>
                                 <!--注意设置-->
                                 <file>${user.dir}/profiles/dev/my.properties</file>
                             </files>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>
         </plugins>
     </build>
     </project>
    
  3. 执行mvn package后,在target/classes/jdbc.properties里能够看到配置文件被成功替换

进阶使用(作用三)

  1. 场景分析:
    1. 项目有开发环境的配置,测试环境的配置;
    2. 并且开发环境是mysql数据库,测试环境是hsqldb数据库;
    3. 最后还要在一个文件中统一打印出配置项内容。
  2. 通过maven的profile来配上properties-maven-plugin实现针对不一样环境的快速打包。
  3. 新增测试环境配置文件:profiles/test/my.properties,内容如下:

     jdbc.driverClassName=org.hsqldb.jdbc.JDBCDriver
     jdbc.url=jdbc:hsqldb:hsql://localhost/stocktest
     jdbc.username=root
     jdbc.password=
     jdbc.validationQuery=SELECT 1 + 1
    
  4. pom.xml 内容如下:

     ...
     <build>
         <resources>
             <resource>
                 <filtering>true</filtering>
                 <directory>${project.basedir}/src/main/resources</directory>
                 <includes>
                     <include>*.properties</include>
                 </includes>
             </resource>
         </resources>
         <plugins>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>properties-maven-plugin</artifactId>
                 <version>1.0-alpha-2</version>
                 <executions>
                     <execution>
                         <id>default-cli</id>
                         <phase>initialize</phase>
                         <goals>
                             <goal>read-project-properties</goal>
                             <!--注意新增-->
                             <goal>write-project-properties</goal>
                         </goals>
                         <configuration>
                             <files>
                                 <!--<file>${user.dir}/profiles/dev/my.properties</file>-->
                                 <file>${user.dir}/profiles/${profile.id}/my.properties</file>
                             </files>
                             <!--输出所有配置项到指定文件-->
                             <outputFile>${build.directory}/profile.properties</outputFile>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>
         </plugins>
     </build>
     <profiles>
         <profile>
             <id>dev</id>
             <activation>
                 <activeByDefault>true</activeByDefault>
             </activation>
             <properties>
                 <profile.id>dev</profile.id>
             </properties>
             <dependencies>
                 <dependency>
                     <groupId>mysql</groupId>
                     <artifactId>mysql-connector-java</artifactId>
                     <version>5.1.31</version>
                     <scope>runtime</scope>
                 </dependency>
             </dependencies>
         </profile>
         <profile>
             <id>test</id>
             <properties>
                 <profile.id>test</profile.id>
             </properties>
             <dependencies>
                 <dependency>
                     <groupId>org.hsqldb</groupId>
                     <artifactId>hsqldb</artifactId>
                     <version>2.2.6</version>
                     <scope>runtime</scope>
                 </dependency>
             </dependencies>
         </profile>
     </profiles>
     </project>
    
  5. 执行命令mvn package -Pdev或者mvn package就能够打一个开发的包。
  6. target/profile.properties里查看项目打包的所有maven用到的配置项。内容如下

     #Properties
     #Wed Sep 23 19:06:47 CST 2015
     jdbc.url=jdbc\:mysql\://localhost/stock?createDatabaseIfNotExist\=true&amp;useUnicode\=true&amp;characterEncoding\=utf-8&amp;autoReconnect\=true
     jdbc.username=root
     jdbc.validationQuery=SELECT 1 + 1
     jdbc.password=
     profile.id=dev
     jdbc.driverClassName=com.mysql.jdbc.Driver
    

分布式项目常用的多环境配置

  1. 中大型企业中项目一般都是分布式项目,一个parent父类n个子项目,可以在parent项目下新建一个config里面存放各种环境的properties文件,进行多环境配置,如下图:

    图

  2. pom文件

     <profiles>
         <profile>
             <id>development</id>
             <activation>
                 <activeByDefault>true</activeByDefault>
             </activation>
             <properties>
                 <profile.id>development</profile.id>
             </properties>
         </profile>
         <profile>
             <id>local</id>
             <properties>
                 <profile.id>local</profile.id>
             </properties>
         </profile>
         <profile>
             <id>test</id>
             <properties>
                 <profile.id>test</profile.id>
             </properties>
         </profile>
         <profile>
             <id>hatest</id>
             <properties>
                 <profile.id>hatest</profile.id>
             </properties>
         </profile>
         <profile>
             <id>production</id>
             <properties>
                 <profile.id>production</profile.id>
             </properties>
         </profile>
     </profiles>
        
     ...
     <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>properties-maven-plugin</artifactId>
         <version>1.0-alpha-2</version>
         <executions>
             <execution>
                 <phase>initialize</phase>
                 <goals>
                     <goal>read-project-properties</goal>
                 </goals>
                 <configuration>
                     <files>
                         <file>${user.dir}/config/${project.profile}.properties</file>
                     </files>
                 </configuration>
             </execution>
         </executions>
     </plugin>
    
  3. 然后根据环境自行打包即可
  4. 可以发现:在全局父项目parent目录下配置个环境的配置变量,然后各个子项目中的xxx.properties、包括springboot的application.yml/properties文件可以直接引用配置的变量,即n个子项目的所有配置都可以在这里配置;
  5. 注意: 项目中的java代码中引用的其实是该项目的xxx.properties、application.yml/properties中的变量,并不是直接引用config中的变量

注意理解

  1. 使用该插件仅仅是为了简化pom文件中的properties属性,其他没有任何改变
  2. pom文件中的properties属性值可以在项目或者子项目的任意xxx.properties文件中引用,包括springboot的application.yml/properties文件

maven-surefire-plugin 插件

简介

  1. Maven本身并不是一个单元测试框架,Java世界中主流的单元测试框架为JUnit和TestNG。Maven所做的只是在构建执行到特定生命周期阶段的时候,通过插件来执行JUnit或者TestNG的测试用例。这一插件就是maven-surefire-plugin,可以称之为测试运行器(Test Runner),他能很好的兼容JUnit3、JUnit4以及TestNG。
  2. surefire是maven里执行测试用例(包括testNG,Junit,pojo)的插件,默认就会存在。
  3. 在默认情况下,maven-surefire-plugin的test目标会自动执行测试源码路径(默认为src/test/java/)下所有符合一组命名模式的测试类。这组模式为:

     **/Test*.java:任何子目录所有命名以Test开头的Java类。
     **/*Test.java:任何子目录下所有命名以Test结尾的Java类。
     **/*TestCase.java:任何子目录下所有命名以TestCase结尾的Java类。
    
  4. 执行的命令为:mvn test 或者 mvn surefire:test,或者直接到IDEA的右侧maven下双击:surefire:test即可
  5. 执行完产生两种不同形式的测试结果报告:
    1. 纯文本/.xml文件格式
    2. 默认情况下,这些文件生成在工程的${basedir}/target/surefire-reports,目录下(basedir指的是pom文件所在的目录)。

基本使用

  1. 项目添加测试用例依赖

     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.8.1</version>
         <scope>test</scope>
     </dependency>
    
  2. 配置maven-surefire-plugin插件(最简单配置,也是maven默认的,可以不写)

     <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-surefire-plugin</artifactId> 
       <version>2.19</version> 
     </plugin>
    
  3. 执行命令:mvn test

    1. 这样就会指定当前项目所有src/test/java/下符合Junit格式的测试用例了
    2. 执行mvn其他命令也会执行这个命令,比如mvn package,执行时先会执行mvn test

常用配置

  1. 下文中的配置项如无特殊说明,都位于<configuration>节点中。

     <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>2.19</version>
         <configuration>
             ...
             配置内容
             ...
         </configuration>
     </plugin>
    

1.跳过测试阶段

<skipTests>true</skipTests>

或者(mvn packge 也一样,打包的时候不执行测试用例)
mvn install -DskipTests

或者(Compliler插件也会根据该参数跳过编译测试类) 
mvn install -Dmaven.test.skip=true

2.忽略测试失败

  1. Maven在测试阶段出现失败的用例时,默认的行为是停止当前构建,构建过程也会以失败结束。有时候(如测试驱动开发模式)即使测试出现失败用例,仍然希望能继续构建项目。
<testFailureIgnore>true</testFailureIgnore> 

或者
mvn test -Dmaven.test.failure.ignore=true

3.包含和排除特定的测试类

  1. surefire默认的查找测试类的模式如下:

     **/Test*.java
     **/*Test.java
     **/*TestCase.java
    
  2. 自定义包含和排除模式,支持ant-style表达式和 正则表达式(%regex[…], 按.class文件匹配而不是.java)

     <includes>
         <include>Sample.java</include>
         <include>%regex[.*[Cat|Dog].*Test.*]</include>
     </includes>
        
     <excludes>
         <exclude>**/TestCircle.java</exclude>
         <exclude>**/TestSquare.java</exclude>
     </excludes>
    

4.运行指定的用例

  1. 指定测试类

     mvn -Dtest=TestClassName test
     mvn -Dtest=TestCi*le test
     mvn -Dtest=TestSquare,TestCi*le test
    
  2. 指定单个测试类中的多个方法(Junit4+, TestNG) 

     mvn -Dtest=TestCircle#mytest test
     mvn -Dtest=TestCircle#test* test
     mvn -Dtest=TestCircle#testOne+testTwo test   #(Surefire2.12.1+, Junit4.x+)
    

更多使用方式,详见地址

Table of Contents