Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!

如果你作为公司核心开发,打算使用maven来搭建项目骨架,这篇文章的内容是你必须要掌握的。

平时我们在开发系统的时候,会有开发环境、测试环境、线上环境,每个环境中配置文件可能都是不一样的,比如:数据库的配置,静态资源的配置等等,所以我们希望构建工具能够适应不同环境的构建工作,能够灵活处理,并且操作足够简单。Maven作为一款优秀的构建工具,这方面做的足够好了,能够很好的适应不同环境的构建工作,本文主要讲解maven如何灵活的处理各种不同环境的构建工作,废话不多说,上干货。

重点提示

本文中的所有案例均在上一篇的b2b项目上进行操作,上一篇还没有看的可以移步过去看一下:Maven系列第8篇:大型Maven项目,快速按需任意构建,必备神技能!相知恨晚!

所有mvn命令均在b2b/pom.xml所在目录执行。

Maven属性

自定义属性

maven属性前面我们有用到过,可以自定义一些属性进行重用,如下:


    5.2.1.RELEASE



    
        org.springframework
        spring-core
        ${spring.verion}
    
    
        org.springframework
        spring-beans
        ${spring.verion}
    
    
        org.springframework
        spring-aop
        ${spring.verion}
    
    
        org.springframework
        spring-web
        ${spring.verion}
    

可以看到上面依赖了4个spring相关的构建,他们的版本都是一样的,在properties元素中自定义了一个spring.version属性,值为spring的版本号,其他几个地方使用${}直接进行引用,这种方式好处还是比较明显的,升级spring版本的时候非常方便,只需要修改一个地方,方便维护。

上面这个是maven自定义属性,需要先在properties中定义,然后才可以在其他地方使用${属性元素名称}进行引用。

maven的属性主要分为2大类,第一类就是上面说的自定义属性,另外一类是不需要自定义的,可以直接拿来使用的。

2类属性在pom.xml中都是采用${属性名称}进行引用,maven运行的时候会将${}替换为属性实际的值。

下面我们来看一下maven中不需要自定义的5类属性。

内置属性
${basedir}:表示项目根目录,即包含pom.xml文件的目录
${version}:表示项目的版本号
POM属性

用户可以使用该属性引用pom.xml文件中对应元素的值,例如${project.artifactId}就可以取到project->artifactId元素的值,常用的有:

${pom.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/
${project.build.testSourceDirectory}:项目的测试源码目录,默认为src/test/java/
${project.build.directory}:项目构建输出目录,默认为target/
${project.build.outputDirectory}:项目主代码编译输出目录,默认为target/classes
${project.build.testOutputDirectory}:项目测试代码编译输出目录,默认为target/test-classes
${project.groupId}:项目的groupId
${project.artifactId}:项目的artifactId
${project.version}:项目的version,与${version}等价
${project.build.finalName}:项目打包输出文件的名称,默认为${project.artifactId}-${project.version}
Settings属性

这种属性以settings.开头来引用~/.m2/settings.xml中的内容,如:

${settings.localRepository}

指向用户本地仓库的地址。

java系统属性

所有java系统属性都可以使用maven属性来进行引用,例如${user.home}指向了当前用户目录。

java系统属性可以通过mvn help:system命令看到。

环境变量属性

所有的环境变量都可以使用env.开头的方式来进行引用,如:

${env.JAVA_HOME}

可以获取环境变量JAVA_HOME的值。

用户可以使用mvn help:system命令查看所有环境变量的值。

上面的maven属性,我们在pom.xml中通过${属性名称}可以灵活的引用,对我们写pom.xml文件帮助还是比较大的。

实操案例

将下面配置放在b2b-account-service/pom.xml中:


    
    ${pom.build.sourceDirectory}
    
    ${project.build.testSourceDirectory}
    
    ${project.build.directory}
    
    ${project.build.outputDirectory}
    
    ${project.build.testOutputDirectory}
    
    ${project.groupId}
    
    ${project.artifactId}
    
    ${project.version}
    
    ${project.build.finalName}

    
    
    ${settings.localRepository}

    
    
    ${user.home}

    
    ${env.JAVA_HOME}

然后在b2b/pom.xml所在目录执行下面命令:

D:\code\IdeaProjects\b2b>mvn help:effective-pom -pl :b2b-account-service > 1.xml

上面这个命令会将mvn ...执行的结果输出到b2b/1.xml目录,mvn这段命令有看不懂的朋友,可以去看看前面的文章。

b2b目录中产生了一个1.xml,如下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第1张图片

我们打开1.xml看一下,部分内容如下:


  D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\main\java
  ${settings.localRepository}
  C:\Users\Think
  D:\installsoft\Java\jdk1.8.0_121
  D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\test\java
  D:\code\IdeaProjects\b2b
  D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
  D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\classes
  D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\test-classes
  com.javacode2018
  b2b-account-service
  1.0-SNAPSHOT
  b2b-account-service-1.0-SNAPSHOT

大家去和上面的pom.xml中的对比一下,感受一下!

多套环境构建问题

b2b-account-service会操作数据库,所以我们需要一个配置文件来放数据库的配置信息,配置文件一般都放在src/main/resources中,在这个目录中新建一个jdbc.properties文件,内容如下:

jdbc.url=jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

现在系统需要打包,我们运行下面命令

mvn clean package -pl :b2b-account-service

问题来了:

上面jdbc的配置的是开发库的db信息,打包之后生成的jar中也是上面开发环境的配置,那么上测试环境是不是我们需要修改上面的配置,最终上线的时候,上面的配置是不是又得重新修改一次,相当痛苦的。

我们能不能写3套环境的jdbc配置,打包的时候去指定具体使用那套配置?

还是你们聪明,maven支持这么做,pom.xml的project元素下面提供了一个profiles元素可以用来对多套环境进行配置。

在讲profiles的使用之前,需要先了解资源文件打包的过程。

理解资源文件打包过程

我们将src/main/resouces/jdbc.properties复制一份到src/test/resources目录,2个文件如下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第2张图片

我们先运行一下下面命令:

mvn clean package -pl :b2b-account-service

输出如下:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.572 s
[INFO] Finished at: 2019-11-21T17:13:20+08:00
[INFO] ------------------------------------------------------------------------

再去看一下项目的target目录,如下图:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第3张图片

下面我们来对这个过程做详细分析:

从输出中可以看到有下面几行:

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource

从上面输出中可以看出,使用了插件maven-resources-plugin的resources目标,将src/main/resouces目录中的资源文件复制到了target/classess目录,复制了一个文件,复制过程中使用是GBK编码。

还有几行输出如下:

[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource

从上面输出中可以看出,使用了插件maven-resources-plugin的testResources目标,将src/main/resouces目录中的资源文件复制到了target/classess目录,复制了一个文件,复制过程中使用是GBK编码。

resources目录中的文件一般放的都是配置文件,配置文件一般最好我们都不会写死,所以此处有几个问题:

  1. 这个插件复制资源文件如何设置编码?

  2. 复制的过程中是否能够对资源文件进行替换,比如在资源文件中使用一些占位符,然后复制过程中对这些占位符进行替换。

maven-resources-plugin这个插件还真好,他也想到了这个功能,帮我们提供了这样的功能,下面我们来看看。

设置资源文件复制过程采用的编码

这个之前有提到过,有好几种方式,具体可以去前面的文章看一下。这里只说一种:


    UTF-8

设置资源文件内容动态替换

资源文件中可以通过${maven属性}来引用maven属性中的值,打包的过程中这些会被替换掉,替换的过程默认是不开启的,需要手动开启配置。

修改src/main/resource/jdbc.properties内容如下:

jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

修改src/test/resource/jdbc.properties内容如下:

jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

b2b-account-service/pom.xml中加入下面内容:


    
    UTF-8
    jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
    root
    root

开启动态替换配置,需要在pom.xml中加入下面配置:


    
        
            
            ${project.basedir}/src/main/resources
            
            true
        
    
    
        
            
            ${project.basedir}/src/test/resources
            
            true
        
    

注意上面开启动态替换的元素是filtering

上面build元素中的resourcestestResources是用来控制构建过程中资源文件配置信息的,比资源文件位于哪个目录,需要复制到那个目录,是否开启动态过滤等信息。

resources元素中可以包含多个resource,每个resource表示一个资源的配置信息,一般使用来控制主资源的复制的。

testResources元素和testResources类似,是用来控制测试资源复制的。

最终pom.xml内容如下:



    4.0.0

    com.javacode2018
    b2b-account-service
    1.0-SNAPSHOT

    
        
        UTF-8
        jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
        root
        root
    

    
        
            com.javacode2018
            b2b-account-api
            ${project.version}
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        
    


运行下面命令看效果:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.798 s
[INFO] Finished at: 2019-11-21T17:53:48+08:00
[INFO] ------------------------------------------------------------------------

4个文件截图看一下效果,如下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第4张图片

target中的2个资源文件内容被动态替换掉了。

上面会将资源文件中${}的内容使用maven属性中的值进行替换,${}中包含的内容默认会被替换,那么我们是否可以自定义${}这个格式,比如我希望被##包含内容进行替换,这个就涉及到替换中分隔符的指定了,需要设置插件的一些参数。

自定义替换的分隔符

自定义分隔符,需要我们配置maven-resources-plugin插件的参数,如下:


    
        org.apache.maven.plugins
        maven-resources-plugin
        2.6
        
            
            false
            
            
                $*$
                ##
            
        
    

delimiters中可以配置多个delimiter,可以配置#*#,其中的*表示属性名称,那么资源文件中的#属性名#在复制的过程中会被替换掉,*前后都是#,表示前后分隔符都一样,那么可以简写为#,所以#*##写法是一样的,我们去看一下源码,delimiters的默认值如下:

this.delimiters.add("${*}");
this.delimiters.add("@");
案例

我们将pom.xml修改成下面这样:



    4.0.0

    com.javacode2018
    b2b-account-service
    1.0-SNAPSHOT

    
        
        UTF-8
        jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
        root
        root
    

    
        
            com.javacode2018
            b2b-account-api
            ${project.version}
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        

        
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    
                    false
                    
                    
                        $*$
                        ##
                    
                
            
        
    


将两个jdbc.properties修改成下面这样:

jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

再运行一下下面的命令:

mvn clean package -pl :b2b-account-service

看一下target/classes中的jdbc.properties文件,变成了下面这样:

jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

可以看到后面两符合分隔符的要求,被替换了,第一个没有被替换。

指定需要替换的资源文件

src/main/resources中新增一个const.properties文件,内容如下:

[email protected]
jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

执行下面命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.667 s
[INFO] Finished at: 2019-11-21T18:26:01+08:00
[INFO] ------------------------------------------------------------------------

看一下target/classes中,如下图:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第5张图片

target/classes/const.properties内容变成下面这样了:

[email protected]
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

说明const.properteis也被替换了。2个资源文件都被复制到了target中,如果我们不想让cont.properties被复制到target/classes目录,我们怎么做?我们需要在资源构建的过程中排除他,可以使用exclude元素信息进行排除操作。

修改pom.xml中resources元素配置如下:


    
        
        ${project.basedir}/src/main/resources
        
        true
        
            **/jdbc.properties
        
        
            **/const.properties
        
    

上面使用includes列出需要被处理的,使用excludes排除需要被处理的资源文件列表,采用通配符的写法,**匹配任意深度的文件路径,*匹配任意个字符。

再执行下面命令:

mvn clean package -pl :b2b-account-service

再看一下target/classes中,如下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第6张图片

const.properties被排除了,确实没有被复制过来。

如果此时我想让const.propertis只是被复制到target下面,但是不要去替换里面的内容,该怎么做呢?此时需要配置多个resouce元素了,如下案例。

多个resource元素的使用案例

修改pom.xml中resources,如下:


    
        
        ${project.basedir}/src/main/resources
        
        true
        
            **/jdbc.properties
        
    
    
        ${project.basedir}/src/main/resources
        
            **/const.properties
        
    

现在pom.xml内容如下:



    4.0.0

    com.javacode2018
    b2b-account-service
    1.0-SNAPSHOT

    
        
        UTF-8
        jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
        root
        root
    

    
        
            com.javacode2018
            b2b-account-api
            ${project.version}
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
                
                    **/jdbc.properties
                
            
            
                ${project.basedir}/src/main/resources
                
                    **/const.properties
                
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        

        
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    
                    false
                    
                    
                        $*$
                        ##
                    
                
            
        
    


执行命令看效果:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.116 s
[INFO] Finished at: 2019-11-21T18:38:59+08:00
[INFO] ------------------------------------------------------------------------

上面有如下输出:

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource

插件处理了2个资源文件。

我们看一下target/classes目录下两个文件的内容。

jdbc.proerties:

jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

const.properties:

[email protected]
jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

2个资源都被复制到target/classes目录了,只有jdbc.properties中的内容被替换了。

关于资源文件处理的,更详细的过程可以去看这个插件的源码,下面我们来说多环境处理的问题。

使用profiles处理多环境构建问题

maven支持让我们配置多套环境,每套环境中可以指定自己的maven属性,mvn命令对模块进行构建的时候可以通过-P参数来指定具体使用哪个环境的配置,具体向下看。

profiles元素支持定义多套环境的配置信息,配置如下用法:


    测试环境配置信息
    开发环境配置信息
    线上环境配置信息
    环境n配置信息

profiles中包含多个profile元素,每个profile可以表示一套环境,profile示例如下:


    dev
    
        dev jdbc url
        dev jdbc username
        dev jdbc password
    

id:表示这套环境的标识信息,properties可以定义环境中使用到的属性列表。

执行mvn命令编译的时候可以带上一个-P profileid来使用指定的环境进行构建。

指定环境进行构建

b2b-account-service/pom.xml加入下面配置:


    
    
        dev
        
            dev jdbc url
            dev jdbc username
            dev jdbc password
        
    
    
    
        test
        
            test jdbc url
            test jdbc username
            test jdbc password
        
    
    
    
        prod
        
            test jdbc url
            test jdbc username
            test jdbc password
        
    

将pom.xml的project->properties中的下面几个元素干掉,这些和profile中的重复了,需要干掉:

jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
root
root

此时pom.xml内容如下,建议大家直接贴进去:



    4.0.0

    com.javacode2018
    b2b-account-service
    1.0-SNAPSHOT

    
        
        UTF-8
    

    
    
        
        
            dev
            
                dev jdbc url
                dev jdbc username
                dev jdbc password
            
        
        
        
            test
            
                test jdbc url
                test jdbc username
                test jdbc password
            
        
        
        
            prod
            
                prod jdbc url
                prod jdbc username
                prod jdbc password
            
        
    

    
        
            com.javacode2018
            b2b-account-api
            ${project.version}
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
                
                    **/jdbc.properties
                
            
            
                ${project.basedir}/src/main/resources
                
                    **/const.properties
                
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        

        
            
                org.apache.maven.plugins
                maven-resources-plugin
                2.6
                
                    
                    false
                    
                    
                        $*$
                        ##
                    
                
            
        
    


修改src/main/resource/jdbc.properties内容如下:

jdbc.url=$jdbc.url$
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

运行下面的构建命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service -Pdev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.361 s
[INFO] Finished at: 2019-11-21T18:51:16+08:00
[INFO] ------------------------------------------------------------------------

注意上面命令中多了一个-Pdev参数,-P后面跟的是pom.xml中profile的id,表示需要使用那套环境进行构建。此时我们使用的是dev环境,即开发环境。

看一下target/classes/jdbc.properties,内容变成了下面这样:

jdbc.url=dev jdbc url
jdbc.username=dev jdbc username
jdbc.password=dev jdbc password

上面文件的内容和pom.xml中dev的profile中的properties对比一下,内容是不是一样的,说明资源文件中内容被替换为了dev环境的配置,我们再来试试test环境,执行下面命令:

mvn clean package -pl :b2b-account-service -Ptest

看一下target/classes/jdbc.properties,内容变成了下面这样:

jdbc.url=test jdbc url
jdbc.username=test jdbc username
jdbc.password=test jdbc password

看到了么,神奇的效果出现了,test环境起效了。

开启默认环境配置

我们在执行下面命令:

mvn clean package -pl :b2b-account-service

看一下target/classes/jdbc.properties,内容变成了下面这样:

jdbc.url=$jdbc.url$
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

内容没有被替换,因为我们没有通过-P来指定具体使用哪个环境进行构建,所以出现了这种现象。

但是我们可以指定一个默认开启的配置,我们默认开启dev的配置,修改dev的profile元素,在这个元素下面加上:


    true

activeByDefault表示默认开启这个环境的配置,默认值是false,这个地方我们设置为true,表示开启默认配置。

此时dev的配置如下:


    dev
    
        true
    
    
        dev jdbc url
        dev jdbc username
        dev jdbc password
    

执行下面命令:

mvn clean package -pl :b2b-account-service

看一下target/classes/jdbc.properties,内容变成了下面这样:

jdbc.url=dev jdbc url
jdbc.username=dev jdbc username
jdbc.password=dev jdbc password

这次我们没有指定环境,默认使用了dev环境。

通过maven属性来控制环境的开启

刚才上面说了通过-P profileId的方式来指定环境,现在我们想通过自定义的属性值来控制使用哪个环境。

可以在profile元素中加入下面配置


    
        属性xx
        属性xx的值
    

那么我们可以在mvn后面跟上下面的命令可以开启匹配的环境:

mvn ... -D属性xx=属性xx的值

-D可以通过命令行指定一些属性的值,这个前面有讲过,-D后面的属性会和activation->properties中的name、value进行匹配,匹配成功的环境都会被开启。

将pom.xml中profiles元素修改成下面这样:



    
    
        dev
        
            true
            
                env
                env_dev
            
        
        
            dev jdbc url
            dev jdbc username
            dev jdbc password
        
    
    
    
        test
        
            
                env
                env_test
            
        
        
            test jdbc url
            test jdbc username
            test jdbc password
        
    
    
    
        prod
        
            
                env
                env_prod
            
        
        
            prod jdbc url
            prod jdbc username
            prod jdbc password
        
    

运行命令:

mvn clean package -pl :b2b-account-service -Denv=env_prod

target/classes/jdbc.properties内容如下:

jdbc.url=prod jdbc url
jdbc.username=prod jdbc username
jdbc.password=prod jdbc password

说明使用到了prod环境的配置。

启动的时候指定多个环境

可以在-P参数后跟多个环境的id,多个之间用逗号隔开,当使用多套环境的时候,多套环境中的maven属性会进行合并,如果多套环境中属性有一样的,后面的会覆盖前面的。

运行下面命令看效果:

mvn clean package -pl :b2b-account-service -Pdev,test,prod

修改pom.xml中的profiles元素,如下:



    
    
        dev
        
            true
            
                env
                env_dev
            
        
        
            dev jdbc url
        
    
    
    
        test
        
            
                env
                env_test
            
        
        
            test jdbc username
        
    
    
    
        prod
        
            
                env
                env_prod
            
        
        
            prod jdbc password
        
    

注意看一下上面3个环境中都只有一个自定义属性了

下面我们同时使用3个环境,执行下面命令:

mvn clean package -pl :b2b-account-service -Pdev,test,prod

target中的jdbc.properties文件变成了这样:

jdbc.url=dev jdbc url
jdbc.username=test jdbc username
jdbc.password=prod jdbc password
查看目前有哪些环境
命令:
mvn help:all-profiles
案例:
D:\code\IdeaProjects\b2b>mvn help:all-profiles -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-help-plugin:3.2.0:all-profiles (default-cli) @ b2b-account-service ---
[INFO] Listing Profiles for Project: com.javacode2018:b2b-account-service:jar:1.0-SNAPSHOT
  Profile Id: dev (Active: true , Source: pom)
  Profile Id: prod (Active: false , Source: pom)
  Profile Id: test (Active: false , Source: pom)

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.527 s
[INFO] Finished at: 2019-11-21T19:16:34+08:00
[INFO] ------------------------------------------------------------------------

从输出中可以看到有3个环境,他们的id,默认激活的是那个等信息。

查看目前激活的是哪些环境
命令:
mvn help:active-profiles
案例:
D:\code\IdeaProjects\b2b>mvn help:active-profiles -pl :b2b-account-service -Ptest,prod
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-help-plugin:3.2.0:active-profiles (default-cli) @ b2b-account-service ---
[INFO]
Active Profiles for Project 'com.javacode2018:b2b-account-service:jar:1.0-SNAPSHOT':

The following profiles are active:

 - test (source: com.javacode2018:b2b-account-service:1.0-SNAPSHOT)
 - prod (source: com.javacode2018:b2b-account-service:1.0-SNAPSHOT)



[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.387 s
[INFO] Finished at: 2019-11-21T19:25:56+08:00
[INFO] ------------------------------------------------------------------------

从输出中可以看到启用了2套环境,分别是testprod

新问题:配置太分散了

我们的系统中有2个模块需要用到数据库的配置,这两个模块是:

b2b-account-service
b2b-order-service

上面我们介绍了b2b-account-service不同环境的构建操作,是在pom.xml中进行配置的,b2b-order-service中数据的配置也可以这么做,如果以后有更多的模块都需要连接不同的数据库,是不是每个模块中都需要配置这样的pom.xml,那时候数据库的配置分散在几十个pom.xml文件中,如果运维需要修改数据库的配置的时候,需要去每个模块中去修改pom.xml中的属性,这种操作会让人疯掉的,我们可以怎么做?

我们可以将数据库所有的配置放在一个文件中,运维只用修改这一个文件就行了,然后执行构件操作,重新发布上线,就ok了。

maven支持我们这么做,可以在profile中指定一个外部属性文件xx.properties,文件内容是这种格式的:

key1=value1
key2=value2
keyn=value2

然后在profile元素中加入下面配置:


    
        xx.properties文件路径(相对路径或者完整路径)
    

上面的filter元素可以指定多个,当有多个外部属性配置文件的时候,可以指定多个来进行引用。

然后资源文件复制的时候就可以使用下面的方式引用外部资源文件的内容:

xxx=${key1}
案例

新建文件b2b/config/dev.properties,内容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=dev_account_jdbc_url
b2b-account-service.jdbc.username=dev_account_jdbc_username
b2b-account-service.jdbc.password=dev_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=dev_order_jdbc_url
b2b-order-service.jdbc.username=dev_order_jdbc_username
b2b-order-service.jdbc.password=dev_order_jdbc_password

新建文件b2b/config/test.properties,内容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=test_account_jdbc_url
b2b-account-service.jdbc.username=test_account_jdbc_username
b2b-account-service.jdbc.password=test_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=test_order_jdbc_url
b2b-order-service.jdbc.username=test_order_jdbc_username
b2b-order-service.jdbc.password=test_order_jdbc_password

新建文件b2b/config/prod.properties,内容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=prod_account_jdbc_url
b2b-account-service.jdbc.username=prod_account_jdbc_username
b2b-account-service.jdbc.password=prod_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=prod_order_jdbc_url
b2b-order-service.jdbc.username=prod_order_jdbc_username
b2b-order-service.jdbc.password=prod_order_jdbc_password

b2b-account-service/src/main/resource/jdbc.properties文件内容:

jdbc.url=${b2b-account-service.jdbc.url}
jdbc.username=${b2b-account-service.jdbc.username}
jdbc.password=${b2b-account-service.jdbc.password}

看到了没,这里面${}中的属性名称取的是上面b2b/config目录中资源文件中的属性名称。

b2b-order-service/src/main/resource/jdbc.properties文件内容:

jdbc.url=${b2b-order-service.jdbc.url}
jdbc.username=${b2b-order-service.jdbc.username}
jdbc.password=${b2b-order-service.jdbc.password}

b2b-account/pom.xml内容如下:



    4.0.0

    com.javacode2018
    b2b-account-service
    1.0-SNAPSHOT

    
        
            com.javacode2018
            b2b-account-api
            ${project.version}
        
    

    
        
        UTF-8
    

    
    
        
        
            dev
            
                true
                
                    env
                    env_dev
                
            
            
                
                    ../../config/dev.properties
                
            
        
        
        
            test
            
                
                    env
                    env_test
                
            
            
                
                    ../../config/test.properties
                
            
        
        
        
            prod
            
                
                    env
                    env_prod
                
            
            
                
                    ../../config/prod.properties
                
            
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        
    


b2b-order/pom.xml内容如下:



    4.0.0

    com.javacode2018
    b2b-order-service
    1.0-SNAPSHOT

    
        
            ${project.groupId}
            b2b-account-api
            ${project.version}
        
        
            ${project.groupId}
            b2b-order-api
            ${project.version}
        
    

    
        
        UTF-8
    

    
    
        
        
            dev
            
                true
                
                    env
                    env_dev
                
            
            
                
                    ../../config/dev.properties
                
            
        
        
        
            test
            
                
                    env
                    env_test
                
            
            
                
                    ../../config/test.properties
                
            
        
        
        
            prod
            
                
                    env
                    env_prod
                
            
            
                
                    ../../config/prod.properties
                
            
        
    

    
        
            
                
                ${project.basedir}/src/main/resources
                
                true
            
        
        
            
                
                ${project.basedir}/src/test/resources
                
                true
            
        
    


见证奇迹的时刻来了。

执行下面命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service,:b2b-order-service -Pdev
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] b2b-account-service                                                [jar]
[INFO] b2b-order-service                                                  [jar]
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT                          [1/2]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO]
[INFO] -----------------< com.javacode2018:b2b-order-service >-----------------
[INFO] Building b2b-order-service 1.0-SNAPSHOT                            [2/2]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-order-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-order-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-order-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-order-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-order-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-order-service ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-order-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\target\b2b-order-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for b2b-account-service 1.0-SNAPSHOT:
[INFO]
[INFO] b2b-account-service ................................ SUCCESS [  2.510 s]
[INFO] b2b-order-service .................................. SUCCESS [  0.257 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.026 s
[INFO] Finished at: 2019-11-21T20:11:32+08:00
[INFO] ------------------------------------------------------------------------

看一下两个模块target/classes下面jdbc.properties内容,如下图:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第7张图片

使用了dev环境的配置,dev环境中处理资源文件替换的时候采用了config/dev.properties文件的内容,这部分配置如下,重点在于build->filters元素


    dev
    
        true
        
            env
            env_dev
        
    
    
        
            ../../config/dev.properties
        
    

我们再使用prod环境看一下效果,执行下面命令:

mvn clean package -pl :b2b-account-service,:b2b-order-service -Pprod

效果图如下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第8张图片

感受一下,这次使用了b2b/config/prod.properties文件的内容对资源文件进行了替换,这次将所有配置的信息集中在config目录的几个文件中进行处理了,对于运维和开发来说都非常方便了。

profile元素更强大的功能

profile元素可以用于对不同环境的构建进行配置,project中包含的元素,在profile元素中基本上都有,所以profile可以定制更复杂的构建过程,不同的环境依赖的构件、插件、build过程、测试过程都是不一样的,这些都可以在profile中进行指定,也就是说不同的环境所有的东西都可以通过profile元素来进行个性化的设置,这部分的功能有兴趣的大家可以自己去研究一下,截个图大家感受一下:

Maven系列第9篇:多环境构建,作为核心开发,这个玩不转有点说不过去!_第9张图片

从上图中可以看出这些属性都可以根据环境进行定制的。

还是那句话,上面这些用法大家会经常用到的,建议大家下去了多练练。看和操作,所获取到的是不能比的,看的过程中可能觉得一切都知道了,但是实际操作就不一样了,可能中间会遇到各种问题,然后自己会想办法解决这些问题,领会和学到的东西是不一样的!

你可能感兴趣的:(maven,maven,java)