第9篇:多环境构建支持
maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能。
这是maven系列第9篇。
整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部有maven完整系列的连接。
如果你作为公司核心开发,打算使用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,如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o0EdCVjF-1629908711725)(media/ee106032a5c0c744fab1c008c3c9bbbf.png)]
我们打开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:
jdbc.username=root
jdbc.password=root
现在系统需要打包,我们运行下面命令
mvn clean -pl :b2b-account-service
问题来了:
上面jdbc的配置的是开发库的db信息,打包之后生成的jar中也是上面开发环境的配置,那么上测试环境是不是我们需要修改上面的配置,最终上线的时候,上面的配置是不是又得重新修改一次,相当痛苦的。
我们能不能写3套环境的jdbc配置,打包的时候去指定具体使用那套配置?
还是你们聪明,maven支持这么做,pom.xml的project
元素下面提供了一个profiles
元素可以用来对多套环境进行配置。
在讲profiles的使用之前,需要先了解资源文件打包的过程。
理解资源文件打包过程
我们将src/main/resouces/jdbc.properties
复制一份到src/test/resources
目录,2个文件如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLkgM9eN-1629908711728)(media/cdee9cee49a5bd050882001ccdc31c3d.png)]
我们先运行一下下面命令:
mvn clean -pl :b2b-account-service
输出如下:
D:\code\IdeaProjects\b2b>mvn clean -pl :b2b-account-service
[INFO] Scanning 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 (-clean) @ b2b-account-service ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (-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 (-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (-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 (-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (-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目录,如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lln2jczG-1629908711731)(media/72c66fc1170ef2b6624bc9b053e3529a.png)]
下面我们来对这个过程做详细分析:
从输出中可以看到有下面几行:
[INFO] --- maven-resources-plugin:2.6:resources (-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目录中的文件一般放的都是配置文件,配置文件一般最好我们都不会写死,所以此处有几个问题:
-
这个插件复制资源文件如何设置编码?
-
复制的过程中是否能够对资源文件进行替换,比如在资源文件中使用一些占位符,然后复制过程中对这些占位符进行替换。
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元素中的
resources
和testResources
是用来控制构建过程中资源文件配置信息的,比资源文件位于哪个目录,需要复制到那个目录,是否开启动态过滤等信息。