作者將在這篇文章中分享他在這個試驗中的想法和發現。作者將清楚的說明他是怎樣用SPRing組件替換參考應用中的單態注冊,JDBC代碼,和web的前后端層。作者也會描述他碰到的一個問題還有他是怎樣來解決它的。
叫我來參加會議晚了,就是這次的Spring框架會議。對于你們后來的人來講,Spring已經是一個在Apache 2.0許可下發布的基礎構造代碼庫。它的核心是一個反轉控制容器,在容器的外部開發組已經創建了JDBC和JMS代碼的樣板文件模板,一個web MVC框架,和其他組件。
我之所以參加這個會議晚是因為我不管Spring的成熟度和公開度,我都對它花了很長的時間進行了測試。我的問題是:"Spring到底能給我帶來什么?",為了找到答案,我用Spring的組件替換了現有的一個應用的內臟。通過這次替換我懂得了:我在很早以前就應該用Spring了;應用程序的代碼已經沒有以前那么混亂了,調試和擴展也更加輕易,并且變的更輕因為我能夠開發一些通用的輔助代碼來配合Spring。
我將在這篇文章中分享我在這個試驗中的想法和發現。我將清楚的說明我是怎樣用Spring組件替換參考應用中的單態注冊,JDBC代碼,和web的前后端層。我也會描述我碰到的一個問題還有我是怎樣來解決它的。
接下來的內容不需要你是一個Spring的專家,我會在后面給出Spring資源鏈接。樣例代碼在linux上Spring 1.2.X和JDK1.5.0_07下已通過測試。
原始(舊的)代碼
我不想通過制作一個鮮活的應用來進行試驗,所以我從另外一篇文章中摘錄下我的測試程序。這是一個有2個servlet頁面控制器作為入口點的簡單的java web應用。servlets通過DAO的方式訪問數據庫,DAO從本地數據源取得數據庫鏈接。關聯對象通過單態注冊方式來相互取得。具體有:
SimpleDAO: 從數據庫讀出和寫入信息對象
DbUtil: 方便程序使用JDBC ResultSets, Connections等等。
ObjectRegistry: 單態注冊類,對象之間可以通過它彼此取得。
SetupDataSourceContextListener: 設置JDBC數據源
SetupDBContextListener: 預備(植入的)數據庫
GetDataServlet: 頁面控制器用來顯示數據
PutDataServlet: 頁面控制器用來存儲數據
這是一個非常簡單的應用程序,但它是完全獨立的并且展現了一個多層應用程序的行為。這個小型試驗的一些觀測資料可用于由真實世界轉換的工程應用中。
修改內臟:對象注冊
首先來分析ObjectRegistry類,它是關系型對象粘合層。
package pool_test.util ;
public class ObjectRegistry {
private static ObjectRegistry _instance = new ObjectRegistry() ;
public static ObjectRegistry getInstance(){
return( _instance ) ;
}
private Map _singletons ;
public void put(final String key , final Object obj){
_singletons.put( key , obj ) ;
}
public Object get( final String key ){
return( _singletons.get( key ) ) ;
}
}
ObjectRegistry 實際上是一個String:Object鍵值對的一個Map.你可以將一個對象注冊在一個地方(put()方法),然后在另外的地方得到這個對象(get()方法)。用注冊可以削弱對象依靠因為代碼可以僅僅通過它的通用類型(接口或超類)和查找要害字得到一個對象。而細節-實現,實例化和配置-就留給這段調用put()方法存儲對象的代碼。
它能工作,而且我發現它工作比較頻繁,但它并不完美。缺少put()或者將它放錯地方可能會引起空指針錯誤或棧溢出錯誤。你必須跟蹤對象被存儲注冊的次序,為了確保你不會試圖取的一個不存在的對象。像我在這做的一樣,在小的應用中用ContextListener(一個監聽器)處理實例化命令,但是在一個大的應用中可能就需要你努力去避免一些問題。
舊的單態注冊的另一個問題是暴露的put()操作是java調用?意思是說:一個存儲的對象實現的變更需要重新編譯注冊類-比如為了測試存根你想替換基于數據庫的DAO。我以前犯過一個小錯誤,產品應用中用了DAO 的stub(這里不知道譯成什么意思好?)。在一個比較大的應用中,它可能很難捕捉到,因為它被隱藏在代碼里了。
寫點Spring代碼就能處理這些缺點。這是新的注冊類:
package pool_test.util ;
import org.springframework....applicationContext ;
import org.springframework....ClasspathxmlApplicationContext ;
public class ObjectRegistry {
private ApplicationContext _singletons ;
private ObjectRegistry(){
_singletons = new ClassPathXmlApplicationContext(
new String[] { "spring-objectregistry.xml" }
);
}
public Object get( final String key ){
return( _singletons.getBean( key ) ) ;
}
}
新聞熱點
疑難解答