maven多环境下切换配置文件 resources无效 问题解决

针对这个问题,网上千篇一律都是说 resources怎么配置,但是配了没生效?
那么请亲耐心向下看,看完之后你肯定会感谢我的。(如果觉得有用请高抬贵手给我一些赞,多谢!)

项目是springboot框架的 ,用maven打包发布,用不同的文件夹作为不同环境下的配置文件标识。


image.png

但是发现在pom.xml中配置了profiles + resources 之后,执行mvn clean install 之后,仍然不能按照resources中配置的过滤规则生成数据。(如果你的环境变量是别的方式,也没关系,下面的几个重点看完之后,无论你是什么结构的,任何方式,都可以切换的游刃有余了。)

maven 版本:apache-maven-3.3.3
pom.xml中的,profiles+resources 配置如下(有问题的配置方式,配了无效)

<project>
    ...
    <dependencies>
        <dependency>...</dependency>
    </dependencies>
     
     <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <profiles.active>dev</profiles.active>
            </properties>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <profiles.active>prod</profiles.active>
            </properties>
        </profile>
    </profiles>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <!-- 资源根目录排除各环境的配置,防止在生成目录中多余其它目录 -->
                <excludes>
                    <exclude>environment/dev/**</exclude>
                    <exclude>environment/prod/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/environment/${profiles.active}</directory>
                <includes>
                    <include>**</include>
                </includes>
            </resource>
        </resources>
        
         <plugins>
              .....各种插件
         </plugins>

重点来了,为什么不生效??? 开始疯狂debug+百度,结果千篇一律都是说resouces怎么怎么配置,可是当前代码已经按照这个配置了还是不行!
最后终于找到了可以生效的方式,总结归纳为如下几个重点:

1.<build>下的<resources> 按照网上说的方式定义好就ok了,无非就是excludes+includes的组合方式而已,resouces下的每个resource是按照自上而下的方式一个个顺序加载。

2.plugins中的 maven-resources-plugin 是用来接管项目的 src/main/resources 编译打包过程的,属于打包资源的生成过程。其它的打包插件 比如 maven-jar-plugin, maven-assembly-plugin, 都是用来接管打包资源生成之后的打包方式的。所以如果只是为了做多环境切换的话,直接引入 maven-resources-plugin插件是最简洁有效的配置方式(专人专项)。

3.<resources>...</resources>的配置,一定要声明两个地方才有效,而且 两个地方的配置必须要保证完全一致!这也是 按照网上配置无效的最关键的一个因素,第一个地方是:<build>下直接声明,第二个地方是 <maven-resources-plugin>下的<configuration> 下。具体代码如下:

<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <!-- 先把所有环境的配置全部排除 -->
                <excludes>
                    <exclude>environment/dev/**</exclude>
                    <exclude>environment/prod/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources/environment/${profiles.active}</directory>
                <!-- 再把当前环境的配置引入 -->
                <includes>
                    <include>**</include>
                </includes>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <resources>
                        <resource>
                            <directory>src/main/resources</directory>
                            <!-- 先把所有环境的配置全部排除 -->
                            <excludes>
                                <exclude>environment/dev/**</exclude>
                                <exclude>environment/prod/**</exclude>
                            </excludes>
                        </resource>
                        <resource>
                            <directory>src/main/resources/environment/${profiles.active}</directory>
                            <!-- 再把当前环境的配置引入 -->
                            <includes>
                                <include>**</include>
                            </includes>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
            <plugin>
                  ...其它打包插件,里面不再需要resources配置了。
            </plugin>
      </plugins>
    </build>

4.profiles.active ,变量${profiles.active} 名字千万别写错了,可以先用固定得变量值dev测试,最后再换成 动态变量。

5.filtering 是用来声明 是否开启配置文件的变量替换规则。默认为false,只有在 一个公共配置文件+多个环境变量替换配置文件方式下才有效,如果是我这种在不同环境的文件夹名称下各有各的公共配置文件的话,是完全不需要管这个参数的。以下分别演示以下:

  • A.一个公共配置文件+多个环境变量替换配置文件方式
src/main/resources
  ---application.properties (app_name=xxx, database_url= ${database_url}) 
      ---env_dev
          ---application-dev.properties (database_url= dev_database_url)
      ---env_online
          ---application-online.properties (database_url=online_database_url)

说明:${database_url}是公共配置中的变量占位符,执行打包的时候,会自动把 不同环境文件夹下的 有具体值的 database_url加载到 公共配置中。
  • B.在不同环境的文件夹名称下各有各的公共配置文件
src/main/resources
   ---env_dev
       ---application.properties (app_name=xxx, database_url= dev_database_url) 
   ---env_online
       ---application.properties (app_name=xxx, database_url= online_database_url) 

说明:与A不同的地方在于 ,没有所有环境的公共配置,不需要变量占位符,每个环境文件夹下的都是当前环境的唯一公共配置。

6.开启maven的debug模式吧!(什么?不会开启debug模式?我一开始也不会,都是查出来的,不过你运气好,我直接告诉你吧,加 -X就可以了:install -Pdev -X -f pom.xml ) ,看看打包的时候到底加载到什么配置了,是不是按照你的配置在工作。看日志的时候,主要关注 resouces-plugin 有关的地方,日志中会打印出来执行插件的时候用到了哪些 resouces以及他们的 excludes, includes 是怎么样的。下面简单黏贴我得debug信息中关注的内容作为样例:

  • a). maven-resources-plugin:2.7:copy-resources
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-resources-plugin:2.7:copy-resources from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-resources-plugin:2.7, parent: sun.misc.Launcher$AppClassLoader@18b4aac2]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-resources-plugin:2.7:copy-resources' with basic configurator -->
[DEBUG]   (f) buildFilters = []
[DEBUG]   (f) encoding = utf-8
[DEBUG]   (f) escapeWindowsPaths = true
[DEBUG]   (s) includeEmptyDirs = false
[DEBUG]   (f) nonFilteredFileExtensions = [ttf, ttc, xlsx, xls]
[DEBUG]   (s) outputDirectory = E:\workspaceG7\fms-truck-center\target\classes
[DEBUG]   (s) overwrite = true
[DEBUG]   (f) project = MavenProject: com.chinaway:fms-truck-center:1.0-SNAPSHOT @ E:\workspaceG7\fms-truck-center\pom.xml
[DEBUG]   (s) directory = src/main/resources
[DEBUG]   (s) filtering = true
[DEBUG]   (s) excludes = [environment/dev/**, environment/prod/**]
[DEBUG]   (s) resources = [Resource {targetPath: null, filtering: true, FileSet {directory: src/main/resources, PatternSet [includes: {}, excludes: {environment/dev/**, environment/prod/**}]}}]
[DEBUG]   (f) session = org.apache.maven.execution.MavenSession@499683c4
[DEBUG]   (f) supportMultiLineFiltering = false
[DEBUG]   (f) useBuildFilters = true
[DEBUG]   (s) useDefaultDelimiters = true
[DEBUG] -- end configuration --
  • b). maven-resources-plugin:2.7:resources
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-resources-plugin:2.7:resources from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-resources-plugin:2.7, parent: sun.misc.Launcher$AppClassLoader@18b4aac2]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-resources-plugin:2.7:resources' with basic configurator -->
[DEBUG]   (f) buildFilters = []
[DEBUG]   (f) encoding = utf-8
[DEBUG]   (f) escapeWindowsPaths = true
[DEBUG]   (s) includeEmptyDirs = false
[DEBUG]   (f) nonFilteredFileExtensions = [ttf, ttc, xlsx, xls]
[DEBUG]   (s) outputDirectory = E:\workspaceG7\fms-truck-center\target\classes
[DEBUG]   (s) overwrite = true
[DEBUG]   (f) project = MavenProject: com.chinaway:fms-truck-center:1.0-SNAPSHOT @ E:\workspaceG7\fms-truck-center\pom.xml
[DEBUG]   (s) resources = [Resource {targetPath: null, filtering: false, FileSet {directory: E:\workspaceG7\fms-truck-center\src\main\resources, PatternSet [includes: {}, excludes: {environment/dev/**, environment/prod/**}]}}, Resource {targetPath: null, filtering: false, FileSet {directory: E:\workspaceG7\fms-truck-center\src\main\resources\environment\dev, PatternSet [includes: {**}, excludes: {}]}}]
[DEBUG]   (f) session = org.apache.maven.execution.MavenSession@499683c4
[DEBUG]   (f) supportMultiLineFiltering = false
[DEBUG]   (f) useBuildFilters = true
[DEBUG]   (s) useDefaultDelimiters = true
[DEBUG] -- end configuration --
  • c). maven-resources-plugin:2.7:testResources
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-resources-plugin:2.7:testResources from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-resources-plugin:2.7, parent: sun.misc.Launcher$AppClassLoader@18b4aac2]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-resources-plugin:2.7:testResources' with basic configurator -->
[DEBUG]   (f) buildFilters = []
[DEBUG]   (f) encoding = utf-8
[DEBUG]   (f) escapeWindowsPaths = true
[DEBUG]   (s) includeEmptyDirs = false
[DEBUG]   (f) nonFilteredFileExtensions = [ttf, ttc, xlsx, xls]
[DEBUG]   (s) outputDirectory = E:\workspaceG7\fms-truck-center\target\test-classes
[DEBUG]   (s) overwrite = true
[DEBUG]   (f) project = MavenProject: com.chinaway:fms-truck-center:1.0-SNAPSHOT @ E:\workspaceG7\fms-truck-center\pom.xml
[DEBUG]   (s) resources = [Resource {targetPath: null, filtering: false, FileSet {directory: E:\workspaceG7\fms-truck-center\src\test\resources, PatternSet [includes: {}, excludes: {}]}}]
[DEBUG]   (f) session = org.apache.maven.execution.MavenSession@499683c4
[DEBUG]   (f) supportMultiLineFiltering = false
[DEBUG]   (f) useBuildFilters = true
[DEBUG]   (s) useDefaultDelimiters = true
[DEBUG] -- end configuration --

看到没有,resources-plugin是分成了三部分加载copy-resouces/resources/testResources,而且每一部分的 resouces配置竟然 各不相同!这也是为何要 把 resources声明两次的原因。如果只在build下声明,根本没卵用。

7.如果要确认自己生成的打包文件是否正常,去项目下的targe/classes里面看就好了,它对了,后面打的什么jar啦,tar.gz啦 ,肯定都对了。

好了,重点列完了,总结一下吧:

resouces相同配两次,debug一开看效果,classes对了就成了,拜拜了您呐,咱们有缘再见。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容