初探spring applicationContext在web容器中加載過程
posted @ 2007-11-07 15:06 空杯 閱讀(10740) | 評論 (1) | 編輯 收藏
隨筆 - 9, 文章 - 0, 評論 - 3, 引用 - 0
|
初探spring applicationContext在web容器中加載過程
摘要: 轉載自www.javaworld.com.tw 袁杰 原文
首先從WEB.XML入手
==>web.xml
1
2
3
4
5
6
... 閱讀全文
posted @ 2007-11-07 15:06 空杯 閱讀(10740) | 評論 (1) | 編輯 收藏 JUnit 4 搶先看
from: http://www.ibm.com/developerworks/cn/java/j-junit4.html
JUnit 由 Kent Beck 和 Erich Gamma 開發,幾乎毫無疑問是迄今所開發的最重要的第三方 Java 庫。正如 Martin Fowler 所說,“在軟件開發領域,從來就沒有如此少的代碼起到了如此重要的作用”。JUnit 引導并促進了測試的盛行。由于 JUnit,Java 代碼變得更健壯,更可靠,bug 也比以前更少。JUnit(它本身的靈感來自 Smalltalk 的 SUnit)衍生了許多 xUnit 工具,將單元測試的優勢應用于各種語言。nUnit (.NET)、pyUnit (Python)、CppUnit (C++)、dUnit (Delphi) 以及其他工具,影響了各種平臺和語言上的程序員的測試工作。 然而,JUnit 僅僅是一個工具而已。真正的優勢來自于 JUnit 所采用的思想和技術,而不是框架本身。單元測試、測試先行的編程和測試驅動的開發并非都要在 JUnit 中實現,任何比較 GUI 的編程都必須用 Swing 來完成。JUnit 本身的最后一次更新差不多是三年以前了。盡管它被證明比大多數框架更健壯、更持久,但是也發現了 bug;而更重要的是,Java 不斷在發展。Java 語言現在支持泛型、枚舉、可變長度參數列表和注釋,這些特性為可重用的框架設計帶來了新的可能。 JUnit 的停滯不前并沒有被那些想要廢棄它的程序員所打敗。挑戰者包括 Bill Venners 的 Artima SuiteRunner 以及 Cedric Beust 的 TestNG 等。這些庫有一些可圈可點的特性,但是都沒有達到 JUnit 的知名度和市場占有份額。它們都沒有在諸如 Ant、Maven 或 Eclipse 之類的產品中具有廣泛的開箱即用支持。所以 Beck 和 Gamma 著手開發了一個新版本的 JUnit,它利用 Java 5 的新特性(尤其是注釋)的優勢,使得單元測試比起用最初的 JUnit 來說更加簡單。用 Beck 的話來說,“JUnit 4 的主題是通過進一步簡化 JUnit,鼓勵更多的開發人員編寫更多的測試。”JUnit 4 盡管保持了與現有 JUnit 3.8 測試套件的向后兼容,但是它仍然承諾是自 JUnit 1.0 以來 Java 單元測試方面最重大的改進。 注意:該框架的改進是相當前沿的。盡管 JUnit 4 的大輪廓很清晰,但是其細節仍然可以改變。這意味著本文是對 JUnit 4 搶先看,而不是它的最終效果。 以前所有版本的 JUnit 都使用命名約定和反射來定位測試。例如,下面的代碼測試 1+1 等于 2:
而在 JUnit 4 中,測試是由
使用注釋的優點是不再需要將所有的方法命名為
下面這個方法也同樣能夠工作:
這允許您遵循最適合您的應用程序的命名約定。例如,我介紹的一些例子采用的約定是,測試類對其測試方法使用與被測試的類相同的名稱。例如,
您也可以使用 JDK 5 中新特性(static import),使得與以前版本一樣簡單:
這種方法使得測試受保護的方法非常容易,因為測試案例類現在可以擴展包含受保護方法的類了。
JUnit 3 測試運行程序(test runner)會在運行每個測試之前自動調用
在 JUnit 4 中,您仍然可以在每個測試方法運行之前初始化字段和配置環境。然而,完成這些操作的方法不再需要叫做
甚至可以用
清除方法與此類似。在 JUnit 3 中,您使用
對于 JUnit 4,我可以給它取一個更自然的名稱,并用
與 最后,您不再需要在超類中顯式調用初始化和清除方法,只要它們不被覆蓋即可,測試運行程序將根據需要自動為您調用這些方法。超類中的 JUnit 4 也引入了一個 JUnit 3 中沒有的新特性:類范圍的 例如,假設類中的每個測試都使用一個數據庫連接、一個網絡連接、一個非常大的數據結構,或者還有一些對于初始化和事情安排來說比較昂貴的其他資源。不要在每個測試之前都重新創建它,您可以創建它一次,并還原它一次。該方法將使得有些測試案例運行起來快得多。例如,當我測試調用第三方庫的代碼中的錯誤處理時,我通常喜歡在測試開始之前重定向
沒有必要在每個測試之前和之后都這樣做。但是一定要小心對待這個特性。它有可能會違反測試的獨立性,并引入非預期的混亂。如果一個測試在某種程度上改變了
異常測試是 JUnit 4 中的最大改進。舊式的異常測試是在拋出異常的代碼中放入
該方法不僅難看,而且試圖挑戰代碼覆蓋工具,因為不管測試是通過還是失敗,總有一些代碼不被執行。在 JUnit 4 中,您現在可以編寫拋出異常的代碼,并使用注釋來聲明該異常是預期的:
如果該異常沒有拋出(或者拋出了一個不同的異常),那么測試就將失敗。但是如果您想要測試異常的詳細消息或其他屬性,則仍然需要使用舊式的
也許您有一個測試運行的時間非常地長。不是說這個測試應該運行得更快,而是說它所做的工作從根本上比較復雜或緩慢。需要訪問遠程網絡服務器的測試通常都屬于這一類。如果您不在做可能會中斷該類測試的事情,那么您可能想要跳過運行時間長的測試方法,以縮短編譯-測試-調試周期?;蛘咭苍S是一個因為超出您的控制范圍的原因而失敗的測試。例如,W3C XInclude 測試套件測試 Java 還不支持的一些 Unicode 編碼的自動識別。不必老是被迫盯住那些紅色波浪線,這類測試可以被注釋為
測試運行程序將不運行這些測試,但是它會指出這些測試被跳過了。例如,當使用文本界面時,會輸出一個“I”(代表 ignore),而不是為通過的測試輸出所經歷的時間,也不是為失敗的測試輸出“E”:
但是一定要小心。最初編寫這些測試可能有一定的原因。如果永遠忽略這些測試,那么它們期望測試的代碼可能會中斷,并且這樣的中斷可能不能被檢測到。忽略測試只是一個權宜之計,不是任何問題的真正解決方案。
測試性能是單元測試最為痛苦的方面之一。JUnit 4 沒有完全解決這個問題,但是它對這個問題有所幫助。測試可以用一個超時參數來注釋。如果測試運行的時間超過指定的毫秒數,則測試失敗。例如,如果測試花費超過半秒時間去查找以前設置的一個文檔中的所有元素,那么該測試失敗:
除了簡單的基準測試之外,時間測試也對網絡測試很有用。在一個測試試圖連接到的遠程主機或數據庫宕機或變慢時,您可以忽略該測試,以便不阻塞所有其他的測試。好的測試套件執行得足夠快,以至程序員可以在每個測試發生重大變化之后運行這些測試,有可能一天運行幾十次。設置一個超時使得這一點更加可行。例如,如果解析 http://www.ibiblio.org/xml 花費了超過 2 秒,那么下面的測試就會超時:
JUnit 4 為比較數組添加了兩個
這兩個方法以最直接的方式比較數組:如果數組長度相同,且每個對應的元素相同,則兩個數組相等,否則不相等。數組為空的情況也作了考慮。
JUnit 4 基本上是一個新框架,而不是舊框架的升級版本。JUnit 3 開發人員可能會找到一些原來沒有的特性。 最明顯的刪節就是 GUI 測試運行程序。如果您想在測試通過時看到賞心悅目的綠色波浪線,或者在測試失敗時看到令人焦慮的紅色波浪線,那么您需要一個具有集成 JUnit 支持的 IDE,比如 Eclipse。不管是 Swing 還是 AWT 測試運行程序都不會被升級或捆綁到 JUnit 4 中。 下一個驚喜是,失敗(assert 方法檢測到的預期的錯誤)與錯誤(異常指出的非預期的錯誤)之間不再有任何差別。盡管 JUnit 3 測試運行程序仍然可以區別這些情況,而 JUnit 4 運行程序將不再能夠區分。 最后,JUnit 4 沒有 我對消除了 GUI 測試運行程序并不感到太高興,但是其他更改似乎有可能增加 JUnit 的簡單性。只要考慮有多少文檔和 FAQ 當前專門用于解釋這幾點,然后考慮對于 JUnit 4,您不再需要解釋這幾點了。
當前,還沒有 JUnit 4 的庫版本。如果您想要體驗新的版本,那么您需要從 SourceForge 上的 CVS 知識庫獲取它。分支(branch)是“Version4”(參見 參考資料)。注意,很多的文檔沒有升級,仍然是指以舊式的 3.x 方式做事。Java 5 對于編譯 JUnit 4 是必需的,因為 JUnit 4 大量用到注釋、泛型以及 Java 5 語言級的其他特性。 自 JUnit 3 以來,從命令行運行測試的語法發生了一點變化。您現在使用
Beck 和 Gamma 努力維持向前和向后兼容。JUnit 4 測試運行程序可以運行 JUnit 3 測試,不用做任何更改。只要將您想要運行的每個測試的全限定類名傳遞給測試運行程序,就像針對 JUnit 4 測試一樣。運行程序足夠智能,可以分辨出哪個測試類依賴于哪個版本的 JUnit,并適當地調用它。 向后兼容要困難一些,但是也可以在 JUnit 3 測試運行程序中運行 JUnit 4 測試。這一點很重要,所以諸如 Eclipse 之類具有集成 JUnit 支持的工具可以處理 JUnit 4,而不需要更新。為了使 JUnit 4 測試可以運行在 JUnit 3 環境中,可以將它們包裝在
但是由于 Java 比較多變,所以 JUnit 4 一點都不向后兼容。JUnit 4 完全依賴于 Java 5 特性。對于 Java 1.4 或更早版本,它將不會編譯或運行。
JUnit 4 遠沒有結束。很多重要的方面沒有提及,包括大部分的文檔。我不推薦現在就將您的測試套件轉換成注釋和 JUnit 4。即使如此,開發仍在快速進行,并且 JUnit 4 前景非??春谩1M管 Java 2 程序員在可預見的未來仍然需要使用 JUnit 3.8,但是那些已經轉移到 Java 5 的程序員則應該很快考慮使他們的測試套件適合于這個新的框架,以便匹配。 posted @ 2007-10-29 16:09 空杯 閱讀(305) | 評論 (0) | 編輯 收藏 Spring 與Hibernate的延遲加載和Dao模式
摘要: Hibernate 與延遲加載:
Hibernate 對象關系映射提供延遲的與非延遲的對象初始化。非延遲加載在讀取一個對象的時候會將與這個對象所有相關的其他對象一起讀取出來。這有時會導致成百的(如果不是成千的話) select 語句在讀取對象的時候執行。這個問題有時出現在使用雙向關系的時候,經常會導致整個數據庫都在初始化的階段被讀出來了。當然,你可以不厭其煩地檢查每一個對象與其他對象的關系... 閱讀全文
posted @ 2007-10-29 16:07 空杯 閱讀(816) | 評論 (1) | 編輯 收藏 Hibernate的檢索方式Hibernate的檢索方式Hibernate的檢索方式: 分頁查詢: 檢查單個對象: posted @ 2007-10-29 16:04 空杯 閱讀(1017) | 評論 (0) | 編輯 收藏 MiddlegenIDE的使用最近有朋友發信,說MiddlegenIDE的主頁出了點狀況,登陸上去顯示的內容莫名其妙,給新手使用MiddlegenIDE帶來了困難。本座去看了一下,果然是莫名其妙得厲害。下面總結一個MiddlegenIDE的使用教程吧。
MiddleGen for Hibernate加上Hibernate_Extension工具包,其實就是用來方便我們從先有的數據庫導出表結構,生成對應的hbm、cfg文件與POJO類代碼。MiddleGenIDE則是MiddleGen的Eclipse插件。整套東西已經有很久沒有更新過了。所以雖然本座現在用的eclipse版本3.1.x也能與這個插件正常配合,但是它沒有提供在線update的功能。需要你先下載middlegenide,安裝插件之后重啟Eclipse。如果新開啟的eclipse沒有變化,估計你得用"- clean"參數再重啟一下,或者去刪除configuration文件夾下面對應的文件。 OK,下面講講怎么去用。首先當然要搭建一個環境(我現在把MySQL更新到了5.0,Hibernate和當時一樣是2.1),然后我們建一個表,裝一點數據。MySQL下面建表的腳本如下:
有了表之后,建立一個Java工程。然后在Src文件夾上面右鍵,選擇“New-Other” ![]() 然后會彈出Middelgen Biuld File的選項。因為MiddleGen是一個使用Ant編譯文件來調出IDE的包,所以這個插件實際上就是方便我們用完型填空的方式來編寫這個Biuld File而已。 ![]() 點擊后出現下面的界面,對應的內容一目了然,按照自己的需要填寫即可。 ![]() 下面這張圖是填好后的樣子。和本座一樣沒有使用Hibernate 3的朋友,注意在畫了紅圈的Option選項中把hibernate的版本調低。不然生產的配置文件,會有一個非常詭異的"xml parser無法解析dtd"的錯誤。 ![]() 填好所有的東西就點擊Next進入MiddleGen界面,幾乎不用改任何東西直接點擊Generate就能得到配置文件和POJO類了。 ![]() 另外,如果你需要在MiddleGen中生成的POJO直接帶Xdoclet的標記的話,需要在找到它自帶的模板文件:
然后把下面這行生成xdoclet tag的值改成true:
posted @ 2007-10-29 16:03 空杯 閱讀(2072) | 評論 (0) | 編輯 收藏 Open Session in Test 及自動Rollback
from: http://www.aygfsteel.com/rain1102/articles/117541.html
又是來自Spring這個神奇國度的東西, 你可以讓testCase繼承于AbstractTransactionalDataSourceSpringContextTests,就可以做到Open Session in Test ,解決Hibernate的lazy-load問題;而且接管原來的DAO里的事務控制定義,通過setDefaultRollback(boolean)方法控制最后回滾還是提交,如果默認為回滾,則測試產生數據變動不會影響數據庫內數據。 如果不能繼承于這個基類,可以自己簡單編寫,代碼是這樣的: protected PlatformTransactionManager transactionManager; protected TransactionStatus transactionStatus; protected boolean defaultRollback = true; public void setUp() { transactionManager = (PlatformTransactionManager) ctx.getBean("transactionManager"); transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition()); } public void tearDown() { if (defaultRollback) transactionManager.rollback(this.transactionStatus); else transactionManager.commit(this.transactionStatus); } (注,hibernate太奸詐了,如果全部默認回滾,只會在session里干活,一點不寫數據庫,達不到完全的測試效果。) posted @ 2007-10-29 16:00 空杯 閱讀(285) | 評論 (0) | 編輯 收藏 ServletConfig與ServletContext的區別
from: http://www.aygfsteel.com/software5168/archive/2006/09/05/67752.html
HttpServletRequest,HttpServletResponse:這兩個屬性的作用范圍最小。 時間上:只是本身請求和應答完成就失效,當然轉發是把當前的request對象取出來傳給另一 個資源,其實本身的request對象還是只生存到本次請求結束,response也同樣。 空間上:只能發送請求的客戶端有效。 HttpSession:一次連結到客戶端關閉,時間作用范圍比上面兩個大,空間任用范圍相同。 ServletConfig:從一個servlet被實例化后,對任何客戶端在任何時候訪問有效,但僅對本servlet 有效,一個servlet的ServletConfig對象不能被另一個servlet訪問。 ServletContext:對任何servlet,任何人在任何時間都有效,這才是真正全局的對象。 那么,ServletConfig參數和ServletContext參數到底應該如何使用,如何取得? 一般來說,對整個應用的配置,為了不使用“硬編碼”,應該配置為ServletContext參數,比如字 符集設定。 <web-app> ................. <init-param> <param-name>charset</param-name> <param-value>GB2312</param-value> </init-param> ................. </web-app> 注意以上格式只是2。0以后的標準格式,舊容器(引擎)采用服務商自己的格式配置。注意它的 父元素應該是<web-app>也就是說它是對一個應用作用的。 而如果只有一個特定的servlet要設定的參數,其它servlet不能共享,應該配置為ServletConfig 參數,如一個讀取附件的servlet要用到絕對目錄,而別的servlet不會用到: <servlet> <servlet-name>GetAtt</servlet-name> <servlet-class>mail.GetAttServlet</servlet-class> <init-param> <param-name>absPath</param-name> <param-value>/usr/mail/ax/axman/Maildir/</param-value> </init-param> </servlet> 不用說,因為在<servlet>標簽中已經指定了name和class,也就是說只有mail.GetAttServlet這個 servlet中才能取到path,而別的Servlet是不能取到的。 那么如何訪問這兩個對象的參數呢? 訪問ServletConfig參數: 首先要取得ServletConfig對象,然后調用它的getInitParameter();方法。要訪問 ServletConfig對象,jsp中直接使用config內置對象,但因為你的JSP編譯后的servlet一般不會被 加到web.xml中的,所以一般不會通過jsp來取對本JSP編譯后的servlet的配置參數,那么在servlet 中要得到ServletConfig對象有兩種方法: 在inii()方法中取到:通過init的重載方法傳遞 ..... public class Test extends HttpServlet { ServletConfig config; public void init(ServletConfig config) throws ServletException { this.config = config; } .................. } 然后在下面的方法中就可以訪問config對象。但要注意,為了確保能從構造方法中到到當前servlet的 config對象,應該調用父類的構造方法: ..... public class Test extends HttpServlet { ServletConfig config; public void init(ServletConfig config) throws ServletException { super.init(config); this.config = config; } .................. } 通過getServletConfig()方法直接到時,這樣做的好處是不必調手工傳遞屬性,想在任何時候都可 以得到。 還有第三種方法,要自己實現一些接口,這里作為一般討論就不介紹了。 要訪問ServletContext對象,只要從現有的ServletConfig對象getServletContext()就可以了,然后 調用它的getInitParameter()方法就可以獲取它的參數。 按說:ServletContext對象的作用域比ServletConfig作用域大,為什么要從ServletConfig中到得 ServletContext對象呢?我個人認為:容器保存了很多個ServletContext對象,請求時容器到底取哪一個 給你呢?那就取其中包含ServletConfig信息的那個給你,就是說取ServletConfig對象的父級對象。就好 象HttpSession要從requset中取得一樣,就是取那個包含當前requese對象的session對象給你,這只是我 的個人想法,還沒有來得及看具體實現。反正就這么用吧。 posted @ 2007-10-29 15:59 空杯 閱讀(2716) | 評論 (0) | 編輯 收藏 Struts 1.2 的 HTML 標簽嵌套屬性(如user.name)如何加入 JavaScript 表單驗證Struts 里面的 public class User { private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } }
public class UserForm extends FormBean { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
那么對應的 JSP 頁面里的 Tag 可以寫成: <html:text property="user.username" /> 但是如果這時候有人還想給生成的表單加入 JavaScript 驗證的話, 必須用下面的寫法才能通過: 這是因為 Struts 標簽最后產生的 HTML 如下所示:
<form onsubmit="return validateForm(this);"> <input name="user.username" /> < SPAN>form>
直接引用 元素.user.username 肯定會出錯的. 正確的方法參考上上面的代碼段即可. posted @ 2007-10-29 15:57 空杯 閱讀(1065) | 評論 (1) | 編輯 收藏 FormBean 與 POJO 的集成代碼
![]() ![]() ![]() ![]() ![]() ![]() 在校驗文件validation.xml中: 代碼 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 在action中如下調用:
代碼 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 其實這樣子的集成感覺很不錯的,除了少了dto和轉換(至少你要用一個copyProperty吧),pojo實現了序列化, 甚至可以直接深入到Hibernate底層,這樣子就省缺了以前一直討論formbean和po是不是合并或者在哪個層面上進 行轉換。 posted @ 2007-10-29 15:54 空杯 閱讀(329) | 評論 (0) | 編輯 收藏 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||