web项目根据profiles动态配置各环境的properties和logback.xml

前情提要: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>**/*.xml</include>
                </includes>
<!--                不处理如下配置中包含的资源类型-->
                <excludes>
                    <exclude>**/logback.xml</exclude>
                </excludes>
                <!--目标处理主资源目下的资源文件时,是否对主资源目录开启资源过滤-->
                <filtering>false</filtering>
            </resource>
            <resource>
                <!--目录不为src/main/resources主目录时,处理后的资源文件默认输出到主目录,
                也可以使用targetPath来指定输出到哪个目录-->
                <directory>src/main/resources/entry/${env}</directory>
                <includes>
                    <include>**/*.properties</include>
                    <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鼠标也点不进去),这个不影响,虽然编译器找不到,但是打包之后对应的目录下会有配置文件,项目可以运行,没有任何问题。

### 关于 Logback.xml 的引入与配置 LogbackJava 平台上的一个日志框架,广泛用于记录应用程序运行中的各种事件。对于 Spring Boot 应用程序,默认情况下会自动寻找 `logback-spring.xml` 或者 `logback.xml` 文件来作为日志系统的配置依据。 #### 是否必须引入 logback.xml? 并非强制要求引入 `logback.xml` 文件。Spring Boot 提供了一套默认的日志配置机制,在未提供自定义日志配置的情况下,它将使用内置的默认设置完成基本功能[^2]。然而,为了满足更复杂的需求(如调整日志级别、指定输出位置或格式化日志消息),通常建议通过创建并引入自己的 `logback.xml` 来覆盖这些默认行为。 #### 如何正确进行配置? 1. **外部资源引用** 如果希望在 `logback.xml` 中引用其他外部文件的内容,则可以利用 `<property>` 节点下的 `resource` 属性实现这一点。例如: ```xml <configuration> <!-- 定义外部属性 --> <property resource="external.properties"/> <!-- 使用该属性 --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${log.file.name}</file> <!-- 假设 external.properties 中有此变量 --> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="FILE" /> </root> </configuration> ``` 2. **加载顺序注意事项** 当涉及到多个配置文件时需要注意它们之间的加载优先级关系。具体来说,`bootstrap.yml` 的解析发生在应用上下文初始化之前,并且它的内容会影响诸如日志这样的早期启动组件;而 `application.yml` 则是在之后被处理。因此如果尝试仅依靠后者去影响前者的行为可能不会生效——比如试图让位于类路径之外某个特定目录里的 `logback.xml` 成为主配置源就需要特别小心其声明时机。 3. **推荐实践:使用 springProfile 支持环境区分** 另一种常见做法是借助 Spring Profiles 功能根据不同部署场景动态切换不同的 logging setup: ```xml <springProfile name="dev"> <appender .../> ... </springProfile> <springProfile name="prod"> <appender .../> ... </springProfile> ``` 上述方式允许开发者针对开发测试生产等多种模式分别定制最合适的方案而不必担心混淆或者冲突问题发生。 ```python # 示例 Python 代码片段无关本主题,仅为演示Markdown支持多语言高亮特性。 def example_function(): pass ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值