起这样一个文章标题,是因为,当前的Java企业项目中,普遍适用Maven构建的,而项目中又普遍适用到了Spring框架、Spring boot框架。这三项技术中,都提供了对于多环境配置的支持。都是profile
。
我们在这里不是说要选择其中一个配置技术来讲。而是,这三个多环境配置技术有关联的地方
,所以,我们不得不不放在一起来讲,而且,我们在实际使用的过程中,也要选择其中的一项来使用,而不是去综合使用。
我的倾向性和明显,就是使用Maven的profile来配置。原因如下:
- maven的配置在IDEA、eclipse这些开发工具中得到很好的集成支持,可以手动点选切换;
- maven的配置是在打包过程中生效,在打完包之后,你就可以提早发现有没有环境切换的问题;
- spring或者spring boot总的来说是一种多环境配置技术,是在项目启动过程中,切换环境配置的,发现问题相对滞后,并且要激活环境配置,要么是手动修改配置文件,要么就是在启动项目的时候,在命令行中添加激活环境的参数,都不是很优雅。
所以,我们的主题,就是要说maven的多环境切换配置,讲的过程中,也要说到与spring,spring boot关联或者冲突的地方。因为,只有解决了这些问题,我们才能说真正的配置好了maven的多环境。
项目结构
首先,我们要讲一下项目的结构,因为这影响到了我们的整个配置思路。在pom.xml中,我们要放置多环境的相关配置。而在filters的目录下,每一个文件对应的每一个环境的具体运行参数。这里,也是体现了我们的整体思路,通过pom.xml的环境切换,来启用filters目录中文件的对应环境中的运行参数。
这里有别于很多其他方案,有的是在pom.xml中就包含了不同环境参数,有的使用了spring的多环境参数,会影响到原来的结构。我都没有选择这些。
pom.xml的profile配置
<profiles>
<!--开发环境配置-->
<profile>
<id>dev</id>
<build>
<filters>
<filter>src/main/filters/dev-filter.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--测试环境配置-->
<profile>
<id>test</id>
<build>
<filters>
<filter>src/main/filters/test-filter.properties</filter>
</filters>
</build>
</profile>
<!--生产环境配置-->
<profile>
<id>prd</id>
<build>
<filters>
<filter>src/main/filters/prd-filter.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</profile>
</profiles>
这块配置,是我们的重头戏,基本上精华都在这里了。
<profile>
标签中的<id>
就是这个运行环境的名称,<filter>
标签的内容,就是这环境要启用的参数。
具体环境参数
我们就拿dev环境的配置文件dev-filter.properties
中的内容来举例。我们看一下这个文件的内容:
很简单,就是一个properties文件,里面全是key-value的配置项。如何启用这些运行参数呢?请看下面<resource>
标签中的配置,里面有一个<filtering>
标签,true的意思,就是对<directory>
配置的目录执行过滤操作。插一句话,我认为这里的filtering(过滤)用的不好,引起很大的歧义。我在初学的时候,在这里也是栽了很大的跟头。你叫个替换,转换,预处理,都比这个强啊。
环境参数应用到项目中
有了当前环境的配置参数,怎么应用到项目中呢?我们拿spring的配置来举例,看下图:
在配置中使用${}
加上环境配置参数的key即可真正的使用了。
真正使用
选择我们要是用的环境配置,然后,执行maven打包即可。在打好的包中,就可以看到替换之后的配置了。
遇到的问题
以上,就是整个的配置流程。
但是,在配置的过程中,也遇到了不少的问题。
-
maven 和 spring 的占位符冲突
maven中的占位符是${}
,而spring的配置文件占位符也是${}
。虽然,这两个技术的启用时机有先后,但是,难免maven执行的时候,已经替换掉参数,影响到spring的占位符启用。我的选择是弃用spring的占位符配置,因为spring的占位符配置实现的功能和我们maven要实现的环境配置切换相冲突。我们把这些外部文件的配置参数放在maven的配置文件中,就完全没有必要再在spring的外部配置文件中配置了,等于脱裤子放屁。
这样做,其实就等于绕过了占位符冲突的问题。
说得此处,就不得不说spring boot了。spring boot比较刚,生硬的解决了这个问题。说起这个事,那又是一段血泪史。我因为不知道此种原因,又是被这个坑活埋。
spring boot 比较叼,直接把maven的占位符标记给替换掉了。请看spring boot 的配置
它把maven的占位符改为了@@
,自己则可以独享${}
这个占位符标记了。这个解决是如此的粗暴,以至于,我在配置maven的profile时,参数始终不能替换,让我怀疑我到底哪里做错了。
-
自定义环境配置
这套环境配置有别于上面所有的环境配置,它不是测试,开发,生产环境。这个环境是为了我自己开发的自定义的环境,我不希望影响到别人的开发环境。或者说这套环境要符合我个人的癖好。这里面也涉及到了spring的启动优化。本来我想尝试配置spring的懒加载,来加速spring的启动速度。但是这个懒加载配置只作用于xml配置的bean,作用范围有限。这个又是一个SSM的框架,并不能像spring boot 那样配置一个全局的懒加载。灵感也是来源于网友。意思就是,通过删减掉与当前开发模块的无用的spring,mybatis的包扫描,类加载等动作,来加速spring容器启动。因为,随着我们的开发接近末期,模块会越来越多。而我们每次开发只是关注于其中一个模块,所以,加载的除此模块之外的其他所有模块都是无用的。顺着这个思路来做。pom.xml中profile配置如下:
<!--自定义环境配置-->
<profile>
<id>mycomputer</id>
<build>
<filters>
<filter>src/main/filters/mycomputer-filter.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>mycomputer/**/*</exclude>
<exclude>applicationContext.xml</exclude>
<exclude>spring-mvc.xml</exclude>
</excludes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources/mycomputer</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</profile>
这个配置在打包之后,得到的配置文件结构与原来没有区别,只是相关配置文件替换成mycomputer
目录下的配置文件了。这是与其他环境配置不同的地方。还有就是,<excludes>
标签与<include>
标签指定的范围发生冲突的时候,以<excludes>
的为准。