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

整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部有maven完整系列的连接。

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

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

重点提示

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

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

Maven属性

自定义属性

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

<properties>
    <spring.verion>5.2.1.RELEASE</spring.verion>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.verion}</version>
    </dependency>
</dependencies>

可以看到上面依赖了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中:

<properties>
    <!-- 项目的主源码目录,默认为src/main/java/ -->
    <a>${pom.build.sourceDirectory}</a>
    <!-- 项目的测试源码目录,默认为src/test/java/ -->
    <b>${project.build.testSourceDirectory}</b>
    <!-- 项目构建输出目录,默认为target/ -->
    <c>${project.build.directory}</c>
    <!-- 项目主代码编译输出目录,默认为target/classes -->
    <d>${project.build.outputDirectory}</d>
    <!-- 项目测试代码编译输出目录,默认为target/test-classes -->
    <e>${project.build.testOutputDirectory}</e>
    <!-- 项目的groupId -->
    <f>${project.groupId}</f>
    <!-- 项目的artifactId -->
    <g>${project.artifactId}</g>
    <!-- 项目的version,与${version}等价-->
    <h>${project.version}</h>
    <!-- 项目打包输出文件的名称,默认为${project.artifactId}-${project.version} -->
    <i>${project.build.finalName}</i>

    <!-- setting属性 -->
    <!-- 获取本地仓库地址-->
    <a1>${settings.localRepository}</a1>

    <!-- 系统属性 -->
    <!-- 用户目录 -->
    <a2>${user.home}</a2>

    <!-- 环境变量属性,获取环境变量JAVA_HOME的值 -->
    <a3>${env.JAVA_HOME}</a3>
</properties>

然后在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,如下:

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

<properties>
  <a>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\main\java</a>
  <a1>${settings.localRepository}</a1>
  <a2>C:\Users\Think</a2>
  <a3>D:\installsoft\Java\jdk1.8.0_121</a3>
  <b>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\test\java</b>
  <b2>D:\code\IdeaProjects\b2b</b2>
  <c>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target</c>
  <d>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\classes</d>
  <e>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\test-classes</e>
  <f>com.javacode2018</f>
  <g>b2b-account-service</g>
  <h>1.0-SNAPSHOT</h>
  <i>b2b-account-service-1.0-SNAPSHOT</i>
</properties>

大家去和上面的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个文件如下:

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

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目录,如下图:

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

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

[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这个插件还真好,他也想到了这个功能,帮我们提供了这样的功能,下面我们来看看。

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

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

<properties>
    <encoding>UTF-8</encoding>
</properties>

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

资源文件中可以通过${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中加入下面内容:

<properties>
    <!-- 指定资源文件复制过程中采用的编码方式 -->
    <encoding>UTF-8</encoding>
    <jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
    <jdbc.username>root</jdbc.username>
    <jdbc.password>root</jdbc.password>
</properties>

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

<build>
    <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>
</build>

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

上面build元素中的resources和<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值