淘先锋技术网

首页 1 2 3 4 5 6 7

前情提要:web项目中的配置文件一般有开发环境dev,测试环境test,生产环境prd的区分,每次本地运行测试或者打包都需要手动修改web.xml或者spring.xml(因为一般各个环境的配置文件都是在这2个XML中配置加载的),很麻烦还容易忘。最近突然发现我们公司其他项目组有在maven中配置profiles,可以通过在maven插件上点击选择,直接就能打包运行所选的环境。如图 1:

研究了一波,我这边将不同环境的logback配置文件也集成到里面了,需要实现的目标是:在idea的maven插件这,只需要用鼠标打钩所需环境直接打包就可以使用所选环境的properties配置文件和logback.xml文件。

实现过程记录一下:

1.配置文件结构

src/main/resources/dev   目录是开发环境的配置文件

src/main/resources/prd   目录是生产环境的配置文件

src/main/resources/test   目录是测试环境的配置文件

各个环境的jdbc.properties里的数据库配置都不同,每个logback.xml日志的打印级别,appender输出都有所不同(dev只输出控制台,prd需要输出文件等)。

2.pom.xml文件添加如下配置:

        <build>
        <!--要打包的资源文件,结合profile中的env标签-->
        <resources>
            <resource>
                <!--目录为src/main/resources主目录时,处理后的资源文件输出到本身所在的目录-->
                <directory>src/main/resources</directory>
<!--                只处理如下配置中包含的资源类型-->
                <includes>
                    <include>**logback.xml</exclude>
                </excludes>
                <!--目标处理主资源目下的资源文件时,是否对主资源目录开启资源过滤-->
                <filtering>false</filtering>
            </resource>
            <resource>
                <!--目录不为src/main/resources主目录时,处理后的资源文件默认输出到主目录,
                也可以使用targetPath来指定输出到哪个目录-->
                <directory>src/main/resources/entry/${env}</directory>
                <includes>
                    <include>**logback.xml</include>
                </includes>
<!--                默认${build.outputDirectory}目录下,如配置src则表示${build.outputDirectory}/src-->
<!--                <targetPath>src</targetPath>-->   <!--此处不指定,默认输出主目录 -->
                <!--是否进行过滤-->
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>


    <!-- 打包环境配置 开发环境dev 测试环境test 正式环境prd -->
    <profiles>
        <profile>
            <!--不同环境Profile的唯一id-->
            <id>dev</id>
            <!--未指定环境时,默认打包dev-->
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <!--env标签(名字随便起),自定义字段可以有多个-->
                <!-- 这里为每个profile都定义一个名为env的properties,可以在配置文件里被引用,
                也可以结合pom文件里的resource和filter属性,作为文件名的一部分或者文件夹名的一部分-->
                <env>dev</env>
            </properties>
        </profile>
        <profile>
            <id>test</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <env>test</env>
            </properties>
        </profile>
        <profile>
            <id>prd</id>
            <properties>
                <env>prd</env>
            </properties>
        </profile>
    </profiles>

resources标签:

maven默认是将src/main/resources下的所有配置文件都会打包,打包后的结构也不会变,这样的话无法实现通过勾选图1中的dev,prd,test环境来加载对应的配置文件,因为每个配置文件的路径都不同,切换环境的话还得在加载配置文件的XML中修改路径。所以这里我们使用resources标签来控制打包后配置文件的结构。

resources标签表示maven生命周期的process-resources阶段执行maven-resources-plugin插件的resources目标,此处配置了两次resources,所以resources目标会执行两次

第一次是将主目录src/main/resources下的除了logback.xml以外所有xml都打包,结果就是将config下的spring.xml和spring-mvc.xml打包,打包出来依旧在config目录下。

第二次是根据profiles标签的配置,动态的将src/main/resources/entry/dev目录,src/main/resources/entry/prd目录,src/main/resources/entry/test目录

下的jdbc.properties和logback.xml打包至主目录,也就是src/main/resources(打包后在WEB-INF/classes/)下。图1里勾选的哪个环境,就打包哪个目录下的2个文件。

profiles标签:

profiles配置是用来区分环境,三个profile表示三个环境,profile的id标签的值就是图1里的勾选框,properties下的env标签是自定义标签,名字随便起,作用就是properties下的标签类似于map键值对, <env>dev</env>就表示env=dev,要引用值可以使用${env},引用{env}就等于dev。引用的值可以作为文件名的一部分或者文件夹名的一部分来使用。在resources我是作为文件夹名来使用的。

那么为什么要这样配置resources标签和profiles标签呢?

首先按照原始结构,之前如果我打dev环境的包,我的jdbc.properties在spring.xml中的引用肯定要写成:

<context:property-placeholder location="classpath:entry/dev/jdbc.properties"/>

logback.xml是在web.xml中要写成:

<listener>
    <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>
<context-param>
    <param-name>logbackConfigLocation</param-name>
    <param-value>classpath:entry/dev/logback.xml</param-value>
</context-param>

如果我要切换prd环境就必须手动修改路径,entry/dev/改为entry/prd/,很麻烦。

但是我使用上面的resources标签和profiles标签打完包后的配置文件结构如图所示:

 

jdbc.properties和logback.xml文件是根据我在图1里的maven插件中勾选的环境,将对应的文件夹下的配置文件打包到主目录(classes目录)的,spring.xml和spring-mvc.xml依然在本来的config目录下。

那么我就可以这样写(只读主目录的配置文件,因为主目录的配置文件就是根据图1勾选的环境所打包出来的配置文件):jdbc.properties在spring.xml中

<!-- jdbc配置 jdbc.properties文件maven会根据配置打包在classpath下,此处匹配不到不影响-->
<context:property-placeholder location="classpath:jdbc.properties"/>

然后logback.xml是在web.xml中

<listener>
    <listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>
<context-param>
    <param-name>logbackConfigLocation</param-name>
    <param-value>classpath:logback.xml</param-value>
</context-param>

这样就实现了在maven插件中勾选环境就可以打包出对应环境的配置文件。

注意一点:上面配置spring.xml中的classpath:jdbc.properties和web.xml中的classpath:logback.xml会显示找不到(按住ctrl鼠标也点不进去),这个不影响,虽然编译器找不到,但是打包之后对应的目录下会有配置文件,项目可以运行,没有任何问题。