感覺在設計模式當中,很多很多地方都要用到反射。尤其是從配置文件當中讀取信息,並使用這個信息來動態加載。反射的應用特別常見,這裏再一次的討論反射和相關概念。
ClassLoader的類加載機制:
l Java當中的類不是一次性都加載到內存當中
l 而是需要的時候才動態的加載到內存當中,也就是說是運行期間的動態加載。
l 靜態的語句是在加載後執行一次,而且執行一次
l Dynamic語句塊每次new新的對象都會執行。
Java當中的ClassLoader很多:
Bootstrap class loader 最頂層的CL,負責管理class。可能是用c或者是彙編寫的。不允許用戶訪問。
Extension class loader
Application class loader
Other class loaders
n Secure class loader
n URL clas loader
感覺還是在配置文件當中讀取類的名字,反射最常見。
1. 屬性文件的位置:
不要寫死在某個目錄當中
也不要用相對路徑(考慮放在jar包當中的情況)
最常用的位置,放到classpath裏面。就可以被properties訪問到了。在eclipse當中體現爲放在src目錄下。Src編譯好的東西,會被eclipse放到當前項目的classpath當中,所以能被properties訪問了。
2. 屬性文件的內容:
observers=com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog
observers爲鍵。
com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.observer.Dog爲值,中間用逗號隔開。
3. 使用者當中,通過一個PropertyMgr的輔助類,來得到配置文件當中的信息。
class PropertyMgr {
//使用系統對象,properties,要求配置文件放在classpath裏面
privatestatic Propertiesprops =new Properties();
static {
try {
//通過properties找到配置文件
//注意這裏必須使用try catch。
props.load(Test.class.getClassLoader().getResourceAsStream("com/bjsxt/dp/observer/observer.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
//通過getProperty來獲取屬性的值。就是在配置文件,後面的部分
publicstatic StringgetProperty(String key) {
returnprops.getProperty(key);
}
}
事實上,得到了屬性的值還沒有完成,得到的是一個字符串。需要繼續通過string的split方法來得到每一個類。然後再生成這些類的對象們。
//對properties得到的字符串,用split來處理
String[] observers = PropertyMgr.getProperty("observers").split(",");
//對每個類,都生成對象,注意這裏要try catch
for(String s : observers) {
try {
c.addWakenUpListener((WakenUpListener)(Class.forName(s).newInstance()));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}