使用Maven和Spring的profile功能實現不同運行環境的無縫切換

1、設計目標,在使用maven構建(build)時即確定運行環境
運行環境包括:數據庫切換,各種配置文件變動,變量的變化
2、實現方式,配置maven的profile和properties,配置spring beans的profile實現層次加載

3、多種實現方式對比

一、糟糕的實現方式

每一種環境建立一個文件夾,文件夾中存放環境所需的全量數據,配置的重複度高。如果需要更新配置,必須把所有的環境都修改。如果有10個或以上的環境,那搞起來就讓人罵娘了,改動的越多出錯的概率越大。這些都是冗餘的東西,相同的配置都是可以提取"公因式"的,沒必要每一個環境都配一遍。

二、好的實現

原則:

1、不出現重複

2、能夠覆蓋到所有環境

方式:

1、一個公共配置,把所有的配置都覆蓋到,作爲默認的環境,比如是開發環境(dev)

2、不同環境會發生的變化的key,只需要配置變化的即可,使用spring <beans profile> 選擇不同的環境

3、如果某些key每個環境都有變化,可以考慮放在maven的<properties>中,每個環境都作配置,構建的時候會替換

實現:

1、配置多個環境和<properties>,要在maven中作如下配置:

<profiles>
        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <profile.id>local</profile.id>
                <profile.activation>local</profile.activation>
                <profiles.default>local</profiles.default>
                <profiles.active>local</profiles.active>
            </properties>
        </profile>

        <profile>
            <id>test</id>
            <properties>
                <profile.id>test</profile.id>
                <profile.activation>test</profile.activation>
                <profiles.default>test</profiles.default>
                <profiles.active>test</profiles.active>
            </properties>
        </profile>
        <profile>
            <id>production</id>
            <properties>
                <profile.id>test</profile.id>
                <profile.activation>production</profile.activation>
                <profiles.default>production</profiles.default>
                <profiles.active>production</profiles.active>
            </properties>
        </profile>
    </profiles>

注:

1、<id>表示環境的名稱

2、<properties>中的元素可以隨意命名,就是自定義的變量,每個環境中所有key要對應

3、activeByDefault 如果爲true,則該profile是默認的

2、要實現properties中的變量在構建時替換文件中key,則要做如下配置:

<build>
        <finalName>test-web</finalName>
        <resources>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/webapp</directory>
                <includes>
                    <include>**/web.xml</include>
                </includes>
            </resource>
        </resources>
</build>
注:1、resource表示構建時要被掃描到的資源文件

2、includes 表示包含的文件,excludes表示排除的文件

3、filtering爲true時這個resource纔會生效,默認false

可能被覆蓋的文件和key如下圖:


注:1、圖中base 表示公共配置所在,配置全量的key

2、local、test、production表示具體的某個環境特有的數據,是變量和增量數據

3、採用先加載base的內容,後加載具體環境中的內容,後面的會覆蓋前面的,實現方式如下:


<!-- 開發環境配置文件 -->
  <beans profile="local">
    <context:property-placeholder
            location="classpath*:base/*.properties,classpath*:local/*.properties"/>
    <bean id="myList" class="java.util.ArrayList">
      <constructor-arg>
        <list>
          <value>1</value>
          <value>2</value>
          <value>${jdbc.url}</value>
        </list>
      </constructor-arg>
    </bean>
  </beans>

  <!-- 測試環境配置文件 -->
  <beans profile="test">
    <context:property-placeholder
            location="classpath*:base/*.properties,classpath*:test/*.properties" ignore-resource-not-found="true"/>
    <bean id="myList" class="java.util.ArrayList">
      <constructor-arg>
        <list>
          <value>4</value>
          <value>5</value>
          <value>${jdbc.url}</value>
        </list>
      </constructor-arg>
    </bean>
  </beans>

  <!-- 生產環境配置文件 -->
  <beans profile="production">
    <context:property-placeholder
            location="classpath*:base/*.properties,classpath*:production/*.properties"/>
    <bean id="myList" class="java.util.ArrayList">
      <constructor-arg>
        <list>
          <value>7</value>
          <value>8</value>
          <value>${jdbc.url}</value>
        </list>
      </constructor-arg>
    </bean>
  </beans>

注:1、profile=local/test/production,這就是具體的環境

2、context:property-placeholder location=   這裏是加載配置文件路徑,要注意順序,後面的會覆蓋前面的,不是文件級別的覆蓋,是key級別

3、profile的選擇可以使用spring.profiles.default和spring.profiles.active來配置,這兩個變量可以配置在web.xml中,也可以配置在jvm options(-Dspring.profiles.active)


注:1、如果配置在web.xml中,可以繼續提取到maven 的properties中,構建時替換即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章