軟件項目實訓及課程設計指導——如何應用Java反射技術靈活地創建程序類的對象實例
1、如何應用屬性配置文件實現對系統中的配置信息進行讀寫操作
Java中的屬性配置文件主要可以作為軟件應用系統及項目的配置文件,比如許多J2EE的開源框架系統中都提供了屬性配置文件作為該應用框架的對外配置文件——如實現O/R Mapping技術的Hibernate應用框架中的hibernate.properties和Log4J日志系統中的log4j.properties、Struts2應用框架中的struts.properties等屬性配置文件。
在屬性配置文件中一般是以"名字(鍵)—值對"的方式進行存儲,請見下圖所示的Struts2框架中的struts.properties文件內容的示例圖示。

利用JDK系統庫中的java.util.Properties類中的load方法可以加載屬性文件和利用Properties類中的getProperty方法獲得屬性文件中的指定屬性項目。但要注意加載屬性文件的兩種不同的形式:
(1)利用Class類中的getResourceAsStream方法
Class類中的getResourceAsStream方法是查找具有給定名稱的資源,返回 InputStream類型的對象實例。但要注意getResourceAsStream方法是相對于"/"根路徑下的位置,這樣的路徑在J2EE Web應用系統的環境下是指定為絕對路徑,如果不以"/"開頭, 則路徑是相對于這個類所在的包——也就是表示從當前類的classPath路徑找指定的文件。
(2)利用Class類中的getResource方法
Class類中的getResource方法是查找帶有給定名稱的資源路徑并返回一個URL類型的對象實例。下圖所示的程序代碼實例是示例項目銀行賬戶信息管理系統中的ClassNameConfig類的完整代碼示例截圖,其中利用static語句塊完成對屬性文件的一次性加載以提高效率——產生出單例設計模式的編程應用效果,然后再提供getProperty方法獲得指定屬性項目的內容。

2、如何實現對存儲在XML格式的配置文件中的配置信息進行讀寫操作
(1)Java屬性配置文件的方式所存在的問題
由于Java屬性配置文件是采用"名字(鍵)—值對"的方式進行存儲,因此無法體現各個"名字(鍵)"之間的層次關系和樹形結構,也就無法表達復雜的數據關系,從而導致在實際應用中受到一定的限制。
由于XML格式的標準化和XML標簽數據能夠體現數據之間的層次關系,因此應用XML格式的配置文件能夠表達樹形結構的復雜層次性的配置數據關系,能夠體現系統中的各個配置數據之間的層次性,可以應用于邏輯關系更復雜的應用場景中。
(2)在項目中采用XML格式的配置文件代替屬性配置文件
由于在軟件應用系統的配置信息中,各個配置數據之間一般都有一定的層次關系(如父子、前后等);同時為了能夠達到與系統平臺無關的配置應用要求。因此,對示例項目銀行賬戶信息管理系統中的配置信息文件從原來應用Java屬性配置文件的方式重構為XML格式的系統配置文件。下圖所示為示例項目銀行賬戶信息管理系統中的配置文件classNameConfig.xml的內容片段的圖示。

(3)應用JDom實現對XML配置文件進行解析
JDom是一個開源項目,它基于樹型結構,利用純Java的技術對XML文檔實現解析、創建、處理和序列化以及多種操作;并充分利用了Java平臺中的優秀的特征,如:方法重載、回收機制,和后臺處理等提高處理的效率。如下示圖為JDom官方網站中提供的下載JDom系統庫的頁面內容的局部截圖。

因此,在示例項目銀行賬戶信息管理系統的項目中決定采用JDom系統庫實現對XML格式的配置文件進行解析。
(4)在項目中添加JDom的系統包文件
讀者可以在JDom官方網站中提供的下載JDom系統庫文件的頁面中下載JDOM的JAR包文件jdom.jar,然后再將該jdom.jar文件加入到項目的類路徑中。最后的操作結果請見下圖所示。

然后再對項目中的ClassNameConfig類的代碼進行重構、并利用JDom 系統API實現對classNameConfig.xml配置文件中的XML配置信息進行解析。為了避免影響使用ClassNameConfig類的其它程序類代碼產生被動地修改,重構后的程序代碼對外的接口getProperty方法不變。重構后的代碼請見下圖所示。

3、利用Java反射技術動態創建程序類的對象實例
(1)Java反射(Reflection)機制主要提供的功能
Java程序員充分地應用反射技術,能夠在程序代碼中實現在運行時判斷任意一個對象所屬的類類型、也能夠在運行時構造任意一個類的對象實例,當然還能夠在運行時判斷任意一個類所具有的成員變量和方法(通過反射甚至可以調用類中的private方法)和在運行時調用任意一個類對象實例中的方法。
(2)利用Java反射技術動態創建對象實例的基本步驟
首先要獲取一個要操作的類的對象,該對象屬于java.lang.Class類的實例;然后再通過Class類中的newInstance方法動態構造出對應的類的對象實例。下圖所示為示例項目銀行賬戶信息管理系統中動態創建出AccountInfoManageInterface接口對象的工廠類AccountInfoManageFactory的代碼片段。

由于在AccountInfoManageFactory工廠類的newAccountInfoManageBean方法只接收需要創建對象的類名稱,因此可以向該方法傳遞同一接口的不同實現類名稱,也就可以實現創建出不同類的對象實例。提高了工廠類在創建對象的靈活性和代碼的可擴展性。
4、如何應用依賴注入技術高效地創建出對象實例
(1)Spring 應用框架中的控制反轉模式和依賴注入技術
1)Spring應用框架中的控制反轉模式
Spring應用框架的核心在于其提供的控制反轉(IoC,Inversion of Control)容器,而IoC容器最主要實現的功能則是為軟件應用系統提供對象管理方面的實現技術。并幫助軟件應用系統的開發者實現對軟件應用系統中的各個類進行對象實例化、建立對象之間的依賴關系、對象的緩存等與生命周期有關的各個方面的管理功能。
利用控制反轉模式能夠有效地減少對象的請求者對服務提供者的特定實現邏輯的依賴,因為應用系統中的各個組件類不再需要去查找或是實例化它們所依賴的其它的目標組件類的對象實例。
2)Spring 應用框架中的依賴注入技術
依賴注入(DI,Dependency Injection)技術是對控制反轉IoC的具體實現技術,因為它更加準確地描述了控制反轉IoC的設計理念。單純從名字上理解依賴注入的基本意思是:組件之間的依賴關系由容器在運行期決定,也就是由容器(如Spring框架的運行系統程序)動態地創建出目標類的對象實例、并將某種依賴關系注入到目標組件類中。
IoC和DI的技術本質都是希望能夠改變軟件應用系統中程序類之間的各種"依賴"關系——程序類之間的依賴關系由原來直接依賴"目標組件類"改變為依賴于"容器"。
5、Spring框架中的控制反轉模式與GOF工廠模式在實現方式方面的不同點
IOC 是一種使應用程序"邏輯外在化"的設計模式——因為提供服務的組件類的對象實例是被"注入"的而不是被"直接寫入"到請求者(客戶端)的代碼中,并將組件類之間的依賴關系轉移到系統外部的配置文件中,避免在調用類中硬編碼實現相關的功能。這樣將能夠大大地減少服務的請求者對服務提供者的特定實現邏輯的依賴——提高了軟件應用系統中的各個組件類的可移植性和可重用度。
Spring應用框架通過依賴注入技術實現了控制反轉模式,而依賴注入技術的具體實現則又是借用Java語言中的反射技術——Spring IoC容器核心程序依據開發人員在XML配置文件中所定義的類名稱和對應的對象名稱,利用反射技術動態地創建出該類的對象實例,并借助于成員屬性的set方法或者構造方法動態地將所創建出的對象實例注入到目標類中。
6、利用Spring 控制反轉模式以XML配置文件的方式定義需要創建的目標對象
(1)應用IoC進行軟件應用系統開發時的基本要求
首先,軟件應用系統的開發人員不應該再在程序代碼中直接創建出目標類的對象實例,但是需要描述出創建它們的方式和要求。
其次,在服務請求者的程序代碼中不直接完成對服務提供者類對象的實例化工作,而只需要在XML配置文件中描述出所需要的服務組件有關的信息。
最后,程序在運行時,由Spring 應用框架中的IoC容器程序負責創建出這些對象和將這些對象關聯在一起。
(2)利用Spring 應用框架中的依賴注入技術創建對象實例
下圖所示為某個項目中的Spring IoC容器中的XML配置文件定義的片段截圖,在Spring應用框架中提供有屬性注入(Setter Injection)和構造方法注入(Constructor Injection),并通過標簽定義某個類的對象實例的基本信息。

采用Spring應用框架中依賴注入技術能夠更簡潔地實現GOF工廠模式相同的效果,因為Spring應用框架系統程序會對開發人員所提供的XML配置文件中的各個配置項目信息進行解析,然后利用Java語言中的反射技術,并根據在XML配置文件中所給出的類名生成對應的類對象實例。
如何在J2EE系統平臺項目中實現性能監控、安全控制等方面功能
如何應用GOF設計模式中的構建者模式創建復合對象實例
如何應用GOF設計模式中的創建型模式實現松耦合地創建對象實例
如何合理地創建對象實例以降低程序類之間關系的耦合度
軟件項目實訓及課程設計指導—如何在數據持久層中應用DAO模式
如何正確應用Web MVC架構模式分離表示層和模型層耦合關系