web項目部署在不一樣環境中須要修改配置文件的解決方法

web項目部署中存在的配置文件問題:java

web項目以war包的形式,部署在tomcat中,同時項目須要訪問一些其餘的東東,例如訪問數據庫,調用別的項目的API。在開發中,這些須要訪問的外部地址一般以配置文件的形式存在於項目中。以下圖:web

在更換項目的部署環境後,或者調用的外部應用地址發生變化,就須要更改配置文件。spring

最直接的問題:數據庫

    發佈了一個測試包,放在測試環境上,測試經過以後,要將測試包發佈到生產環境中,此時測試環境與生產環境的各類配置的地址是不一樣的,解決方案有兩種apache

(1)將配置文件修改成生產環境的配置,從新打包。tomcat

(2)將測試環境的包,升級到生產環境後,修改配置文件爲生產環境的配置文件。app

無論是哪一種方式都是存在風險的。對於(1)來講升級到生產環境的包並非測試經過的包;對於(2)來講增長了人工成本和出錯機率。spring-boot

解決方案:測試

若是配置文件中,須要變化的地址使用變量的形式,項目在被部署到不一樣的環境中後,讀取各自環境中的變量,是否是就能夠解決這個問題了呢。ui

步驟:

(1)在環境變量中增長一個參數配置,tomcat啓動後或者項目啓動後能夠加載改參數

(2)將項目中的配置文件修改爲已經定義的變量

(3)項目的代碼部分在加載配置文件的時候,能夠自動替換掉變量

具體實現:

(1)修改tomcat的Catalina.sh文件

在cygwin=false上面增長JAVA_OPTS="-DbaseDomain=xxxxxx"

設置了變量以後,在java的項目中可使用System.getProperty("baseDomain")來獲取。

(2)修改項目的配置文件,須要修改的內容使用${baseDomain}替換。

(3)項目中解析${baseDomain}

 

配置完成以後,便可初步實現build once,run any enviroment了。

--------------

附上解析配置文件中${baseDomain}的代碼

import java.util.Properties;

import org.apache.log4j.helpers.LogLog;

public class OptionConverterUtil {
	 static String DELIM_START = "${";
	  static char   DELIM_STOP  = '}';
	  static int DELIM_START_LEN = 2;
	  static int DELIM_STOP_LEN  = 1;
	  
    public static
    String substVars(String val, Properties props) throws
                          IllegalArgumentException {

      StringBuffer sbuf = new StringBuffer();

      int i = 0;
      int j, k;

      while(true) {
        j=val.indexOf(DELIM_START, i);
        if(j == -1) {
  	// no more variables
  	if(i==0) { // this is a simple string
  	  return val;
  	} else { // add the tail string which contails no variables and return the result.
  	  sbuf.append(val.substring(i, val.length()));
  	  return sbuf.toString();
  	}
        } else {
  	sbuf.append(val.substring(i, j));
  	k = val.indexOf(DELIM_STOP, j);
  	if(k == -1) {
  	  throw new IllegalArgumentException('"'+val+
  		      "\" has no closing brace. Opening brace at position " + j
  					     + '.');
  	} else {
  	  j += DELIM_START_LEN;
  	  String key = val.substring(j, k);
  	  // first try in System properties
  	  String replacement = getSystemProperty(key, null);
  	  // then try props parameter
  	  if(replacement == null && props != null) {
  	    replacement =  props.getProperty(key);
  	  }

  	  if(replacement != null) {
  	    // Do variable substitution on the replacement string
  	    // such that we can solve "Hello ${x2}" as "Hello p1" 
              // the where the properties are
  	    // x1=p1
              // x2=${x1}
  	    String recursiveReplacement = substVars(replacement, props);
  	    sbuf.append(recursiveReplacement);
  	  }
  	  i = k + DELIM_STOP_LEN;
  	}
        }
      }
    }
    
    public static String getSystemProperty(String key, String def) {
      try {
        return System.getProperty(key, def);
      } catch(Throwable e) { // MS-Java throws com.ms.security.SecurityExceptionEx
        LogLog.debug("Was not allowed to read system property \""+key+"\".");
        return def;
      }
    }
}

 

在第三步配置文件參數解析操做過程當中參考了log日誌的作法,解析方法也是從log4j的源代碼中copy出來的。

---------------

 

看了一下spring-boot,若是使用spring-boot,則不須要上述設置,直接配置不一樣的配置文件。spring-boot會根據不一樣的環境加載不一樣的配置文件,原理感受和上述相似。

相關文章
相關標籤/搜索