maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明

        本人初来乍到,最近研究如何搭maven框架,那么在maven项目中重中之重就是如何配父模块的pom文件。为了支持不同环境下使用不同的配置文件,有多重多样的方式,之前了解过可以在工程构建打包阶段选择配置文件运行阶段进行配置文件选择,感兴趣的可以查阅:https://blog.csdn.net/halfclear/article/details/80067998;

以上两种方式其实还是要把properties文件打包进去,这种方式其实还不够友好,在工程构建打包阶段选择配置文件方式下进一步通过过滤替换的方式来实现;

目前普遍流行的是以下三种方式:

(1)不同环境同一套xml配置文件模板的场景:不同环境下配置不同的properties文件,共用同一套spring配置,通过不同环境下的properties配置文件替换掉spring中的${key}的方式;

(2)不同环境不同xml配置文件的场景:另一种就是不同环境下使用不同 ×××-spring.xml 配置文件,这种情况下需要指定环境来拿取×××-spring.xml

(3)(1)与(2)相结合使用的场景:在某场景下(1)(2)单独使用并不能满足需求,比如在开发及测试环境下,数据库的读写操作都是用同一个数据库,而在生产环境下,读操作使用一个数据库,写操作用到另一个数据库,那么不同环境下对于数据库的 ds-spring.xml 的配置套路就不同了。

(一)不同环境同一套xml配置文件模板的场景

        比如我们以dev/sit/prod三种环境进行讲解

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第1张图片


在父模块下建立vars包来放三种环境下的properties文件,文件中主要以key-value的方式来存储数据


        
            dev
            
                true
            
            
                
                    ../${project.parent.artifactId}/vars/vars.dev.properties
                
            
        
        
            sit
            
                
                    ../${project.parent.artifactId}/vars/vars.sit.properties
                
            
        
        
            prod            
            
                
                    ../${project.parent.artifactId}/vars/vars.sit.properties
                
            
        


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

        上面是pom文件中的配置不同环境下的properties文件,根据单词filter可以猜到这个配置是干嘛了.他的工作过程就是在打包的时候通过key-value对来过滤${basedir}/src/main/resources中的文件,并将填充完整后的配置文件全部搬运到target/classes(默认位置,如何想改变位置可以通过标签来指定)中去,并且这个过程是覆盖的.   同时true指定了在这个”搬运”过程中,需要进行过滤。  

   从这里介绍的方法可以看出, 配置文件中的参数是在打包的时候才会被真正填充进去的, 那么对于那种希望在Eclipse中调试的项目怎么办.(例如用Jetty插件来调试Maven项目的时候, 并不会将项目打包后来执行, 而是直接运行src/main/webapp作为项目root路径。所以在开发 调试的时候,可以在配置文件的目录中放上完整的配置文件,里面的填充需要的参数,这位就可以顺利进行调试了, 并且不影响打包。


(二)不同环境不同xml配置文件的场景

        这种场景其实讲解第三种场景说明就很明了,其实就是resources下根据不同环境分包dev/sit/prod三种包,每个包下面存放该环境下的配置文件,该文件中不包含占位符,全部都是直接拿来就可以使用的配置文件,方式如下:

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第2张图片

由于每个环境下的配置文件中不包含占位符,所以不需要(一)中通过过滤替换占位符的环节,仅指定maven项目的打包执行环境,这种情况下不需要在标签中配置


        
            
            dev
            
                dev
            
            
                true
            
        
        
            
            sit
            
                sit
            
        
        
            
            prod
            
                prod
            
        
    

    
        
            ${basedir}/src/main/resources/${package.environment}/
        
    
    
        
            ${basedir}/src/test/resources/${package.environment}
        
    

通过与(一)中对比,resource标签中少了true,这是因为在这种模式中没有占位符需要被替换,所以就不需要指定过滤。真正开发过程中,基本上不同环境的配置文件的模板都是通用的只需要通过占位符来控制value的不同,所以这种模式目前很少被采用。

 


(三)(1)与(2)相结合使用的场景

        这种是最常使用的模式,即能满足各个环境通用配置文件模板的使用,又能满足不同环境个性化配置文件的需要,目录结构如下:

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第3张图片

从图中可以看出,对于通用的配置文件的参数properties文件是放在父模块下,以key-value方式存储,用于打包时过滤替换占位符,个性化的配置放在各个模块下,不放在resources文件下,resources下主要存放通用配置文件,先把代码贴出来再做解释


        
            dev
            
                DEV
            
            
                true
            
            
                
                    ../${project.parent.artifactId}/vars/vars.dev.properties
                
            
        
        
            sit
            
                SIT
            
            
                
                    ../${project.parent.artifactId}/vars/vars.sit.properties
                
            
        
        
            prod
            
                PROD
            
            
                
                    ../${project.parent.artifactId}/vars/vars.prod.properties
                
            
        
    

    
    
        
        
            
                
                
                    org.apache.maven.plugins
                    maven-war-plugin
                    
                    
                        ${project.artifactId}
                        
                            
                                src/main/webapp
                                true
                                
                                    **/*.html
                                    **/*.js
                                    **/*.css
                                    **/*.xml
                                    **/*.jsp
                                
                            
                            
                            
                                src/main/web-env/${envName}
                                true
                                WEB-INF/
                            
                        
                    
                
                
                
                    org.apache.maven.plugins
                    maven-compiler-plugin
                    3.8.0
                    
                        1.8
                        1.8
                        UTF-8
                    
                
                
                
                    org.apache.maven.plugins
                    maven-resources-plugin
                    2.6
                    
                        false
                        
                            $[*]
                        
                        UTF-8
                    
                

                
                
                    maven-surefire-plugin
                    2.12.4
                    
                        
                            src/test/testng.xml
                        
                    
                
                
                    org.codehaus.mojo
                    sonar-maven-plugin
                    3.2
                
            
        
        
        
            
                
                ${basedir}/src/main/resources
                
                true
            
        
        
            
            
                ${basedir}/src/test/resources
            
        
    

为了更详细的解释这种模式,先来看看一下的一些问题,原来想把以下的问题单独写个分享,但是为了理解的连贯性,所以就一并放到一起了。

从代码中可以看出,其实 资源文件的配置  可以有两种方法:

  • 一是在元素下添加进行配置。
  • 另一种是在子元素中配置maven-resources-plugin等处理资源文件的插件。

那么这两种方式有什么区别吗?

        首先我们先了解一下编译和打包阶段的细节问题   

我们主要从eclipse中maven目录结构、target文件夹目录结构以及eclipse下tomcat项目目录结构入手作对比来理解。

编译阶段

src/main/java和src/test/java 

        这两个目录中的所有*.java文件会分别在comile和test-comiple阶段被编译,编译结果分别放到了target/classes和targe/test-classes目录中,但是这两个目录中的其他文件都会被忽略掉。

src/main/resouces和src/test/resources

        这两个目录中的文件也会分别被复制到target/classes和target/test-classes目录中。

打包阶段

target/classes

打包插件默认会把这个目录中的所有内容打入到jar包或者war包中。(没有进行特殊的配置,Maven会按照标准的目录结构查找和处理各种类型文件,如果有特殊配置,target下可能会包含target\m2e-wtp\web-resources的路径文件,这个在以下文章中会详细讲解)


 

编译阶段:      

元素下添加进行配置的都会被复制到target/classes下,而子元素中配置maven-resources-plugin等处理资源文件的插件的方式会被复制到target\m2e-wtp\web-resources路径下(该路径是eclipse空间下)。

接下来我们通过代码来验证,将非src\main\resources的资源包放到元素下添加进行配置,如下:


    
         ${basedir}/src/main/resources
         true
    
    
         src/main/web-env/${envName}
         true
    
    

最后编译完成target目录结构如下:

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第4张图片

src/main/web-env/${envName}路径下的文件被复制到target/classes下,即使通过去指定路径,也依然是在classes下延伸的路径而已。


     src/main/web-env/${envName}
     true
     WEB-INF/

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第5张图片

同理:子元素中配置maven-resources-plugin等处理资源文件的插件的方式只会被复制到target\m2e-wtp\web-resources路径下,不管路径如何指定,这里要注意的是,一定要指定在WEB-INF文件夹下,因为不指定的话,最终打包不到WEB-INF包下,如下:

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第6张图片


打包阶段:

 

下图是maven项目编译完成后的target目录结构,项目在tomcat上发布后,

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第7张图片

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第8张图片

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第9张图片maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第10张图片

通过上图分析 编译 -->项目tomcat发布过程:

① 当项目进行编译时,会把src/main/webapp直接照搬进了target\m2e-wtp\web-resources下,修改时间会更新为当前时间;

② 通过eclipse中tomcat下的clean操作,会把src/main/webapp直接照搬进了apache-tomcat-7.0.88\webapps\xxxx项目下;同时,target\m2e-wtp\web-resources下的文件会覆盖掉apache-tomcat-7.0.88\webapps\xxxx项目下同名的文件(通过修改时间来看的话),而且target下的classes文件会直接搬到apache-tomcat-7.0.88\webapps\xxxx项目\WEB-INF下,其中freemarker是在编译时过滤而没有搬到arget\m2e-wtp\web-resources下的文件,在tomcat下的日期仍然是第一次tomcat clean时候的日期,而lib始终是最新的更新日期。

总结:先把src/main/webapp照搬进来,如果存在则不替换,不存在新增,若存在src/main/webapp中没有的则删除,然后再将target\m2e-wtp\web-resources下的文件搬进来进行替换相同的文件


还有一点特别要注意相同路径的问题,下面通过一个例子说明:

对于不同环境特有的配置文件,在打包的时候也想和其他配置文件打包到一起,如图所示,spring-ds.xml是不同环境下特有的配置文件,但是对于打包之后的某一个环境下其实和其他的配置文件没有什么区别,所以这个时候就想把他们打包在一起

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第11张图片

可以通过路径的设置来达到该目的


                    org.apache.maven.plugins
                    maven-war-plugin
                    
                        ${project.artifactId}
                        
                           
                            
                                src/main/web-env/${envName}/spring
                                true
                                WEB-INF/classes/conf/spring
                            
                            
                                ../${project.parent.artifactId}/web-env/${envName}
                                true
                                WEB-INF/
                            
                        
                    
                

将路径改为WEB-INF\classes下的同其他配置文件路径相同的路径,这样编译后的路径就是如下图

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第12张图片

当tomcat clean的时候,target/classes下的路径会被放在WEB-INF下,其实就是和上图路径重合到一起了,所以两路文件就会被放到一起了,如下图

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第13张图片

到此编译打包的路径问题就讲完了,其实我这边并没有使用到打包来做解释,仅仅是通过tomcat的clean操作来作比较而已!

 

通过编译打包的介绍,应该就理解(三)方式的用处了吧!

这里其实有想要多说两句,在web.xml中加载配置文件的路径又是根据哪个目录来的呢?

maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明_第14张图片

我感觉这个应该很好理解啊,web.xml是在tomcat(服务器)启动时加载这些配置文件,那就说这些路径是根据tomcat下的项目目录路径来的。

classpath 路径在每个J2ee项目中都会用到,即WEB-INF下面的classes目录,所以对于spring-ds.xml并非在classes下,所以路径自然不是用classpath来使用。

你可能感兴趣的:(maven配置不同环境动态打包及资源文件配置编译、打包阶段的变化说明)