1. 程式人生 > >自動搜尋不同位置的properties檔案並載入

自動搜尋不同位置的properties檔案並載入

在專案開發中,對於一些程式執行的引數可能經常需要根據實際情況修改或調整,所以這些引數我們不會在程式碼中寫死,而是它們儲存在properties(或xml)檔案中,以方便修改。這時就需要智慧載入要配置檔案,如何智慧載入,我想要的載入順序:

1. jar包所在目錄(載入jar包裡的初始值)
2. 專案所在目錄(呼叫jar的程式)
3. 使用者工作目錄(use.dir)

下面是完整的java程式碼:

package net.gdface.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import
java.net.URL; import java.util.HashSet; import java.util.Properties; import java.util.Set; public class ConfigUtils { /** * 順序載入不同位置的properties檔案,載入順序為:<br> * 1.呼叫{@link ClassLoader#getResource(String)}方法在{@code clazz}所在位置查詢,如果失敗則丟擲異常<br> * 2.如果class在jar包中,則嘗試讀取在jar所在位置../confFolder/propFile,tomcat下即為WEB-INF/confFolder/propFile<br> * 3.如果環境變數envVar定義,則從envVar指定的目錄下讀取propFile<br> * 4.user.dir下查詢confFolder/propFile載入配置<br> * 後面的配置變數會覆蓋前面的定義<br> * @param
propFile 要載入的properties檔名,為{@code null}或空時丟擲異常 {@link IllegalArgumentException} * @param confFolder popFile所在資料夾,{@code null}時使用預設值'conf' * @param envVar 環境變數名 用於定義propFile位置,可為{@code null} * @param clazz 用於獲取 {@link ClassLoader}的類,為null時使用本類的class * @param showProp 載入後是否顯示所有值 * @return
返回載入後的{@link Properties}物件 */
public static Properties loadAllProperties(String propFile, String confFolder, String envVar, Class<?> clazz, boolean showProp) { if(null==propFile||propFile.isEmpty()) throw new IllegalArgumentException("the argument 'propFile' must not be null or empty"); if (null == confFolder) confFolder = "conf"; if (null == clazz) clazz = ConfigUtils.class; final String fileSeparator = System.getProperty("file.separator"); String prop_path = confFolder.concat(System.getProperty("file.separator")).concat(propFile); Properties props = new Properties(); Set<File> loaded_files = new HashSet<File>(); try { // 在jar包中查詢預設配置檔案 URL url = clazz.getClassLoader().getResource(prop_path.replace(fileSeparator, "/")); if(null==url) throw new ExceptionInInitializerError(String.format("not found default properties %s", prop_path)); loadProperties(url, props); } catch (Exception e) { // 預設配置必須載入成功否則丟擲異常 throw new ExceptionInInitializerError(String.format("fail to load default properties(載入預設配置檔案失敗) %s cause by %s", prop_path, e.getMessage())); } try { // 載入 jar包所在位置 ../conf/cassdk.properties URL class_location = clazz.getProtectionDomain().getCodeSource().getLocation(); if (class_location.toString().endsWith(".jar")) { // jar包所在目錄的父目錄,tomcat下即為WEB-INF File jar_parent = new File(class_location.getPath()).getParentFile().getParentFile(); if (null != jar_parent) { File conf_file = new File(jar_parent, prop_path); if (conf_file.isFile()) { loadProperties(conf_file.toURI().toURL(), props); loaded_files.add(conf_file); } } } } catch (Exception e) { } try { // 通過環境變數查詢properties檔案 if (envVar != null && !envVar.isEmpty()) { String cf = System.getProperty(envVar); if (null != cf&&!cf.isEmpty()) { File env_file = new File(cf, propFile); if (!loaded_files.contains(env_file)) { loadProperties(env_file.toURI().toURL(), props); loaded_files.add(env_file); } } else log("not defined environment variable '%s'", envVar); } } catch (Exception e) { } try { // 在當前路徑下查詢配置檔案 File propInUserDir = new File(System.getProperty("user.dir"), prop_path); if (propInUserDir.isFile() && !loaded_files.contains(propInUserDir)) { loadProperties(propInUserDir.toURI().toURL(), props); loaded_files.add(propInUserDir); } } catch (Exception e) { } // 輸出所有引數值 if(showProp) props.list(System.out); return props; } /** * configure with the parameters given in the given url * * @param url * the resource filename to be used * @param props * dest properties to add * @throws IOException */ private static void loadProperties(URL url, Properties props) throws IOException { if (null != url) { InputStream is = null; try { props.load(is = url.openStream()); log("Load properties from %s", url.toString()); } finally { if (is != null) is.close(); } } } /* * 這個類原本是用sl4j做日誌輸出的,因為這裡需要輸出的日誌比較少,<br> * 而且為了增強該類的獨立性減少對第三方jar包的依賴,<br> * 在此改為一個簡單的log方法來輸出資訊,輸出資訊中會包含類名和行號 */ private static void log(String format, Object ... args){ System.out.printf("[%s:%d]%s\n", ConfigUtils.class.getSimpleName(), Thread.currentThread() .getStackTrace()[2].getLineNumber(), String.format(format, args)); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128

如果上面三個目錄裡檔案存在相同的key,後面載入將覆蓋前面的ps: this.class.getProtectionDomain().getCodeSource().getLocation()

如果直接執行.class檔案那麼會得到當前class的絕對路徑:

file:/E:/melt/workspace/bpmsAnalysis/build/classes/

如果封裝在jar包裡面執行jar包那麼會得到當前jar包的絕對路徑:

file:/E:/melt/workspace/bpmsAnalysis/WebContent/WEB-INF/lib/JdbcUtils.jar

通過執行目錄來決定把檔案放src下,還是要WEB-INF下

轉:http://blog.csdn.net/10km/article/details/52100365