在Java開源王國中自由翱翔

在如今的Java領域,各種新技術,新工具層出不窮,一方面,每一種技術都會不停的升級換代,另一方面,還會不斷涌現出新的技術和工具。Java世界就像小時候玩的萬花筒,儘管實質上只是由幾個普通的玻璃碎片組成,但只要輕輕一搖,就會變化出千萬種繽紛的圖案。Java世界如此變化多端,很容易讓初學Java的人有無從下手的感覺。常常會有讀者問我這樣的問題:

我學了Java已經一年多了,現在就只能用Jsp寫點東西,其它的東西實在太多了,我整天學都學不完,很迷惘,不知道該如何有針對性地去學,去找到一份Java工作,現在是困死在Java裏了。

撰寫本文,目的是爲了幫助讀者看清Java萬花筒的本質,從複雜的表象中尋找普遍的規律,只有掌握了普遍的規律,才能以不變應萬變,輕輕鬆鬆的把握Java技術發展的新趨勢,迅速的領略並且會熟練運用一門新的技術,而不成爲被動的追隨者,知其然而不知其所以然。

在尋找普遍規律之前,讓我們先看看Java的發展歷程:
(1)SUN的主流技術的發展
GUI界面:Java AWT API--〉Java Swing API
JavaWeb: Servlet--〉JSP--〉JSF
持久化層:JDBC--〉CMP EJB或BMP EJB或JDO
分佈式應用:Socket--〉RMI--〉J2EE或Java Web Service

(2)主要Java開源軟件的種類
JavaWeb容器: Tomcat、Resin
EJB容器: JBoss
框架: Java Web框架(Struts)、業務邏輯層框架(Spring)
持久化層: DAO、ORM映射工具(如Hibernate、OJB)
工程管理工具:ANT、Elipse
日誌輸出工具: Log4J
JavaWeb服務工具:Apache Axis

促成Java世界如此絢麗多姿的基本動力在於以下核心思想:

接口與實現

不同的軟件系統之間通過接口來交互。軟件系統只對外公開接口,封裝實現細節。接口描述了軟件系統具備的功能,也就是指定軟件系統能夠做什麼,但是沒有指明怎麼去做。接口具有三大作用:

(2)對於接口實現者:接口實現者以特定的方式實現標準的規範。例如一些開放源代碼軟件,如Tomcat和Resin分別以不同的實現方式,實現了標準的Servlet規範。同一個接口允許有多種實現,使得Java領域保持着百花齊放、百家爭鳴的良好勢頭,

(3)對於接口調用者:接口調用者的程序具有良好的可移植性。以JavaWeb應用爲例,由於Tomcat和Resin遵守同樣的規範,因此用戶開發的JavaWeb應用能夠順利的從Tomcat容器移植到Resin容器中。

封裝與抽象

封裝指的是在一個大系統中包含一個小系統,大系統是建立在已有小系統的基礎上的更爲複雜、功能更強大的系統。例如,Hibernate對JDBC API進行了封裝,在Hibernate內部依賴JDBC API來操縱數據庫,但是Hibernate API比JDBC API具有更強大的功能,例如JDBC API只具有連接和操縱數據庫的功能,而Hibernate不僅具備這一功能,還具有對象-關係映射的功能。

抽象是指從已經存在的具有相似功能、但不同接口的系統中抽取共性,提煉出統一的接口。例如,Hibernate Transaction API是對JDBC Transaction API和Java Transaction API(JTA)的抽象。 

繼承與擴展

繼承與擴展是一對孿生兄弟,當兩個類之間存在繼承關係,那麼必定也存在擴展關係。繼承的優點在於提高代碼的可重用性,子類會繼承父類的所有public和protected類型的屬性和方法,在子類的程序代碼中,無需重複定義這些屬性和方法。擴展的優點在於使軟件應用具有可伸縮性,能夠在已有功能的基礎上擴展新的功能。

Struts框架充分運用了擴展思想。Struts框架中的許多類都是供應用程序擴展的,其中最主要的一個是Action類,在Action類中已經定義了一些通用的方法,採用Struts框架的JavaWeb應用將擴展Action類,創建負責特定流程或業務的客戶化的Action類。

對象的生命週期

當一個對象通過new語句創建後,它就會擁有一塊固定的內存空間,如果沒有任何變量引用它,它就會結束生命週期,它佔用的內存空間隨時可能被JVM的垃圾回收器回收。

應用程序如何管理對象的生命週期呢?目前比較流行的做法是把對象存放在一個“範圍”內。例如在JavaWeb應用中,JavaBean可以存放在request、session或application範圍內。每個範圍對應一個對象,例如request範圍對應HttpServletRequest對象,session範圍對應HttpSession對象,application範圍對應ServletContext對象。把一個JavaBean存放在request範圍內,實質上是在HttpServletRequest對象的一個集合屬性中加入這個JavaBean的引用,這個集合屬性也被稱爲HttpServletRequest對象的緩存。

把一個JavaBean存放在request範圍內,等價於以下兩種說法:
把一個JavaBean加入到HttpServletRequest對象的緩存中
把一個JavaBean和HttpServletRequest對象關聯

當JavaBean位於request範圍內,這個JavaBean的生命週期依賴於HttpServletRequest對象的生命週期,當HttpServletRequest對象結束生命週期,並且這個JavaBean也不被應用程序中的其他變量引用,那麼它就會結束生命週期。

那麼HttpServletRequest對象本身的生命週期由誰管理呢?這是由JavaWeb容器(也稱Servlet容器)來管理的。對於每個HTTP請求,JavaWeb容器會自動創建一個HttpServletRequest對象,當HTTP請求的響應完畢,JavaWeb容器就會結束這個對象的生命週期。同理,當每個HTTP會話開始,JavaWeb容器會自動創建一個HttpSession對象,當這個會話結束,JavaWeb容器就會結束這個對象的生命週期;當每個JavaWeb應用啓動時,JavaWeb容器會自動創建一個ServletContext對象,當這個應用被關閉,JavaWeb容器就會結束這個對象的生命週期。

在Hibernate中,在net.sf.hibernate.Session範圍內加入一個持久化對象,實質上是在Session對象的集合屬性中加入這個持久化對象的引用。以下幾種說法是等價的:
在Session範圍內加入一個持久化對象
在Session的緩存中加入一個持久化對象
把一個持久化對象與Session關聯

值得注意的是,Hibernate的Session不僅能管理緩存中持久化對象的生命週期,還會負責按照持久化對象的狀態的變化,來同步更新數據庫。

集成開源軟件的基本步驟

在開發Java應用時,爲了提高開發效率,縮短開發週期,常常需要集成第三方提供的Java軟件,如ORM映射工具Hibernate、MVC框架Struts、日誌工具Log4J和Web服務軟件Apache AXIS等。在自己的應用中集成這些第三方軟件時,大體步驟都很相似。
(1) 把它們的JAR文件拷貝到classpath中。
(2) 創建它們的配置文件(XML格式的文件或者Java屬性文件),這些配置文件通常也位於classpath中。
(3) 在程序中訪問它們的接口。

接口與配置文件,是軟件系統對外公開的兩個主要窗口。無論是Tomcat、Struts還是Hibernate,都離不開配置文件,與編寫程序代碼相比,配置文件能提高軟件的可維護性,更加靈活的適應用戶變化的需求,但是,配置文件不擅長表達非常複雜的邏輯,在這種情況下,必須求助於程序代碼。作爲軟件使用者,如果僅僅想快速掌握一個新的Java軟件的使用方法,而不打算深入瞭解軟件內在原理和結構,無非就是了解它的接口以及配置文件的使用方法。當然,如果想對軟件的運用達到得心應手的地步,還應該瞭解軟件本身的實現原理和結構,而這些軟件無非就是通過抽象、封裝和實現等手段,從簡單的小系統出發,構造出更加複雜,但是對外有着簡潔統一的接口的大系統。

作者:孫衛琴
寫作時間:2005/5
  

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