• maven springboot多环境profile加载不同配置文件自由切换


    1.情景展示

      声明:本文和springboot没有关系,本质是:maven与spring相互作用产生的效果,之所以标题使用它,是为了让更多人看到。

      在实际开发过程中,我们经常会有这样需求:

      开发环境或测试环境,使用测试数据库;生产环境使用正式数据库。

      日志级别、引用的jar包、打包方式有时也会不一样,这样,同一项目就会存在多个运行环境。

      对于初学者而言,通常的做法就是:

      开发的时候在配置文件使用相关配置信息;需要部署项目的时候,再将原有代码注释掉,重新配置一套环境;打完包,在本地调试的时候,再将生产环境配置注销掉,还原开发环境。

      首先,这种方法肯定是可行的,但经常改来改去,不便维护及拓展。

      下面,介绍一种更好的方案。

    2.环境分析

      我们先来了解一下,环境的种类有哪些?

    • 开发环境:development,通常用dev表示;
    • 测试环境:test,通常使用test表示;
    • 预演环境:preview,通常使用prev表示,相当于试运行阶段,处于测试和正式阶段之间;
    • 生产环境:production,通常使用prod表示。

      基本上上面的4种环境,就涵盖了我们研发一种产品的所有阶段。

      这里,需要说明的是:环境的名称是可以自定义的,你可以定义成任何名称,只不过是上面4种是大家约定俗称的名字而已,无论是谁看到,就能立马明白什么意思;而如果你将名字定义成aa,也许只有你自己知道它代表的是哪个环境了。

      下面,我先讲一种大众化的多环境开发模式。

      第一,application.properties/yml,作为spring的主配置文件。

      由该配置文件来决定,哪个配置文件生效。

      通过spring.profiles.active来设置生效的配置文件,如上图所示,我使用的是dev,在启动项目时,spring会加载application-dev.properties

      第二,设置环境配置文件

       这种方式,很简单,容易上手,没什么好说的。

    3.解决方案

       这里,介绍一种更为高级的使用方式。

      通过pom.xml的profile标签来管理环境,换句话说就是:使用maven来完成环境的管理,在使用maven命令进行打包时实现。

      打包形式、打包时是否跳过测试阶段、是否启用接口说明文档、日志级别、以及引用的jar包,通通由profile来管理,实现在多环境中共存。

      先来看看pom.xml的构成吧,关键代码展示:

    <groupId>com.公司简称</groupId>
    <artifactId>项目名称</artifactId>
    <!--打包形式:通过maven的profile来决定打成war包还是打jar包(如果不配置packaging标签的话,默认值是jar)-->
    <packaging>${project.packaging}</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>项目名称</name>
    <description>项目简述</description>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
    </parent>
    
    <properties>
        <!--指定tomcat内置版本(只对springboot内置tomcat生效)-->
        <!--<tomcat.version>8.5.0</tomcat.version>-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!--java版本-->
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!--proguard版本-->
        <proguard.version>6.2.2</proguard.version>
        <!--spring版本号-->
        <spring.version>2.3.1.RELEASE</spring.version>
        <!--打包时是否跳过测试阶段(使用profile来指定打包时是否进行测试)-->
        <skipTests>${skipTests}</skipTests>
    
        <!--加载application-*.yml配置文件(通过该标签来指定即将生效的配置文件)-->
        <!--加载application-test.yml配置文件(profile需要勾选成test)-->
        <spring.profiles.active>test</spring.profiles.active>
        <!--基层(测试环境)-->
        <!--<spring.profiles.active>jc</spring.profiles.active>-->
    
        <!--加载application-prod.yml配置文件-->
        <!--这样,这里就可以根据实际需要,进行多个生产环境间的切换(profile需要勾选成prod)-->
        <!--基层(正式环境)-->
        <!--<spring.profiles.active>jc</spring.profiles.active>-->
    </properties>
    
    <!--根据不同的环境引用不同的jar包,最终统一打包到项目当中-->
    <!--生产环境:prod,开发环境:dev,测试环境:test,预演环境:prev
    使用maven命令打包介绍:
    开发环境打包:mvn clean package -Dmaven.test.skip=true -P dev
    测试环境打包:mvn clean package -Dmaven.test.skip=true -P test
    生产环境打包:mvn clean package -Dmaven.test.skip=true -P prod
    !!!另外,在idea中切换生产环境和开发环境时,需要重新导包!!!-->
    <profiles>
        <!--开发环境-->
        <profile>
            <id>dev</id>
            <activation>
                <!-- 默认激活本环境 -->
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <!--加载application-dev.yml配置文件(profile需要勾选成dev)-->
                <spring.profiles.active>dev</spring.profiles.active>
                <!--environment这个节点是我自己取的:yml文件根据该标签的值来确定接口地址是正式地址还是测试地址-->
                <environment>development</environment>
                <!--是否是生产环境:通过配置该值,来决定是否启用knife4j-->
                <isProduction>false</isProduction>
                <!--日志级别-->
                <logLevel>DEBUG</logLevel>
                <!--打包方式:
                    设置成jar包时,在idea中,不能通过插件的package进行打包,
                    只能通过命令来实现:mvn clean package -Dmaven.test.skip=true -P dev
                -->
                <project.packaging>jar</project.packaging>
                <!--打包时,需要进行测试-->
                <skipTests>true</skipTests>
            </properties>
            <dependencies>
                <!--jsp不能够在jar中使用,只能够在War中使用
                所以,如果确定部署项目的时候以jar的形式运行的话,则项目就不能使用jsp了,
                因为,maven在执行打包命令时,jsp是不会被打包到jar包当中的-->
                <!-- 使用jsp引擎,springboot内置tomcat没有此依赖 -->
                <dependency>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-jasper</artifactId>
                    <version>9.0.36</version>
                </dependency>
                <!--增加对 JSP 文件的支持-->
                <dependency>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jsp-api</artifactId>
                    <version>9.0.36</version>
                </dependency>
                <!-- 添加jstl标签库依赖模块 -->
                <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>jstl</artifactId>
                    <version>1.2</version>
                </dependency>
            </dependencies>
        </profile>
        <!--测试环境-->
        <profile>
            <id>test</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <environment>test</environment>
                <isProduction>false</isProduction>
                <logLevel>INFO</logLevel>
                <project.packaging>war</project.packaging>
                <skipTests>true</skipTests>
            </properties>
            <dependencies>
               <!--引用的jar包与生产环境一样,这里不再展示-->
            </dependencies>
        </profile>
        <!--预演环境-->
        <profile>
            <id>prev</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <environment>preview</environment>
                <isProduction>true</isProduction>
                <logLevel>INFO</logLevel>
                <project.packaging>war</project.packaging>
                <skipTests>true</skipTests>
            </properties>
            <dependencies>
               <!--引用的jar包与生产环境一样,这里不再展示-->
            </dependencies>
        </profile>
        <!--生产环境-->
        <!--在本地通过Application启动项目时,其本质还是使用的springboot的内置tomcat,由于内置tomcat不支持使用jsp,
        所以,此时是无法访问项目对应的jsp页面的,
        只有将其部署在tomcat上并启动SpringBootStartApplication才能正常访问-->
        <profile>
            <id>prod</id>
            <!-- 是否激活本环境 -->
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <environment>production</environment>
                <isProduction>true</isProduction>
                <logLevel>ERROR</logLevel>
                <project.packaging>war</project.packaging>
                <!--打包时,跳过测试阶段(因为测试阶段会去连接数据库,正式数据库本地无法访问,会导致打包失败)-->
                <skipTests>true</skipTests>
            </properties>
            <!--项目中,编译和测试阶段用到的jar包,但tomcat中存在这些jar包,此时,在部署到tomcat中时,我们就需要把它们踢掉-->
            <dependencies>
                <!--内置tomcat(剔除该jar包)-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <!--只有编译和测试阶段生效-->
                    <scope>provided</scope>
                </dependency>
                <!-- servlet依赖(只在开发时使用,因为部署到tomcat上时,tomcat有对应的jar包) -->
                <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>javax.servlet-api</artifactId>
                    <scope>provided</scope>
                </dependency>
                <!-- jstl标签库依赖 -->
                <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>jstl</artifactId>
                    <version>1.2</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
    <!--配置项目的jar包仓库-->
    <repositories>
        <!--阿里云仓库-->
        <repository>
            <id>central</id>
            <name>central maven</name>
            <url>https://maven.aliyun.com/repository/central</url>
            <!--<url>http://maven.aliyun.com/nexus/content/groups/public/</url>-->
        </repository>
        <!--maven官网-->
        <repository>
            <id>public</id>
            <name>public maven</name>
            <url>https://mvnrepository.com</url>
        </repository>
    </repositories>
    <!--jar包依赖-->
    <dependencies>
        <!--公共类封装引用-->
        <dependency>
            <groupId>code.marydon.encapsulation</groupId>
            <artifactId>javaUtils</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
    

      再来看看application.yml主配置文件

      这里的关键点在于:

      yml文件想要引用pom.xml中的property标签的值时,在要引用的标签名称两边加上@,即:@propertyName@;如果是properties文件想要引用,使用的是EL表达式,${propertyName}。

      这样,就将启用的配置文件的决定权交给了pom.xml。

      提示:

      在idea中,按住Ctrl键不松手,会跳转到对应pom.xml该标签所处位置。

      knife4j配置(如果没有,就忽略)

      实现的效果就是:开发环境和测试环境可以访问接口文档,预演环境和生产环境禁止访问。 

      数据库配置、日志配置等自定义配置不在主配置文件里放,放到对应的环境配置文件当中。

      假设,我们需要调用第三方的接口,而第三方接口也分测试地址和正式地址。

      那我们就可以在这里使用自定义标签,把正式接口和测试接口添加到配置文件当中。

      如果没有这种需求,就可以跳过。

     

      这样,我们分别获取到当前生效的是哪种环境,测试接口地址,正式接口地址,根据环境来决定最终调用哪个地址。 

      这只是环境的一种使用方式,还有一种应用场景是:根据环境来控制控制层的是否可见(特定请求只在特定环境生效),下篇文章会讲。 

      最后,来看看日志。

     

      日志级别,也由pom.xml的profile标签来决定。

      通常情况下,开发环境使用debug、测试环境使用info,生产环境使用error。

      每种环境的个性化需求,都可以通过这种方式来实现。

      如何正确使用多环境的切换?

      在idea中,想要项目完成环境的切换,至少需要完成前三步,一般项目在清空target目录后,idea会完成自动编译,如果没有那就是你没有设置自动编译;

      在idea中,经常会出现因idea自带的maven插件因环境切换失败导致项目编译失败的问题,这也没有办法,是idea自身的问题,重复上述步骤即可。 

      原理就是:maven插件会将yml文件中引用的标签的值写入对应的配置文件中。

      补充一点:

     

      如上图所示,一个地方会产生一个配置文件,而每个地方又可分为生产环境和测试环境,这时候,第一种方式就会显得力不从心。

      现在,我们只需要三步即可:

      增加一个配置文件,比如叫做:application-aa.yml;

      在pom.xml中,将原有的<spring.profiles.active>注释掉,添加一个同样的标签<spring.profiles.active>aa</spring.profiles.active>;

      选择要生效的环境,重新编译项目即可。

      这样,就实现了多区域多环境可以随意切换的效果。

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    地图的可视化--Folium
    GIS性能策略
    计算多边形中心线
    生成凹壳
    路径分析之NetworkX实例
    网络分析之networkx(转载)
    网络分析之Pgrouting(转载)
    颜色空间变换(RGB-HSV)
    计算坡度与坡向
    计算山体阴影
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/14197828.html
Copyright © 2020-2023  润新知