posts - 37,comments - 7,trackbacks - 0
          http://www-128.ibm.com/developerworks/cn/opensource/os-ecl-ajax/index.html?S_TACT=105AGX52&S_CMP=techcsdn
          posted @ 2006-09-07 13:42 Dave 閱讀(170) | 評論 (0)編輯 收藏
          http://www.sergiopereira.com/articles/prototype.js.html
          posted @ 2006-08-10 15:06 Dave 閱讀(214) | 評論 (0)編輯 收藏
          http://blog.csdn.net/calvinxiu/archive/2006/08/08/1036306.aspx
          posted @ 2006-08-10 13:02 Dave 閱讀(179) | 評論 (0)編輯 收藏
          http://java.csdn.net/n/20060807/93375.html
          posted @ 2006-08-10 13:01 Dave 閱讀(191) | 評論 (0)編輯 收藏
          http://java.csdn.net/n/20060808/93473.html
          posted @ 2006-08-10 12:59 Dave 閱讀(275) | 評論 (0)編輯 收藏
          https://compdoc2cn.dev.java.net/prototype/html/prototype.js.cn.html
          posted @ 2006-08-10 12:50 Dave 閱讀(201) | 評論 (0)編輯 收藏
          定義:一個正則表達式,就是用某種模式去匹配一類字符串的一個公式。
          正則表達式由一些普通字符和一些元字符(metacharacters)組成。普通字符包括大小寫的字母和數字,而元字符則具有特殊的含義,我們下面會給予解釋。

          元字符?描述


          .
          匹配任何單個字符。例如正則表達式r.t匹配這些字符串:ratrutr t,但是不匹配root。?
          $
          匹配行結束符。例如正則表達式weasel$ 能夠匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。?
          ^
          匹配一行的開始。例如正則表達式^When in能夠匹配字符串"When in the course of human events"的開始,但是不能匹配"What and When in the"。
          *
          匹配0或多個正好在它之前的那個字符。例如正則表達式.*意味著能夠匹配任意數量的任何字符。
          \
          這是引用府,用來將這里列出的這些元字符當作普通的字符來進行匹配。例如正則表達式\$被用來匹配美元符號,而不是行尾,類似的,正則表達式\.用來匹配點字符,而不是任何字符的通配符。
          [ ]?
          [c1-c2]
          [^c1-c2]
          匹配括號中的任何一個字符。例如正則表達式r[aou]t匹配ratrotrut,但是不匹配ret。可以在括號中使用連字符-來指定字符的區間,例如正則表達式[0-9]可以匹配任何數字字符;還可以制定多個區間,例如正則表達式[A-Za-z]可以匹配任何大小寫字母。另一個重要的用法是“排除”,要想匹配除了指定區間之外的字符——也就是所謂的補集——在左邊的括號和第一個字符之間使用^字符,例如正則表達式[^269A-Z] 將匹配除了2、6、9和所有大寫字母之外的任何字符。
          \< \>
          匹配詞(word)的開始(\<)和結束(\>)。例如正則表達式\<the能夠匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:這個元字符不是所有的軟件都支持的。
          \( \)
          將 \( 和 \) 之間的表達式定義為“組”(group),并且將匹配這個表達式的字符保存到一個臨時區域(一個正則表達式中最多可以保存9個),它們可以用 \1\9 的符號來引用。
          |
          將兩個匹配條件進行邏輯“或”(Or)運算。例如正則表達式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:這個元字符不是所有的軟件都支持的。
          +
          匹配1或多個正好在它之前的那個字符。例如正則表達式9+匹配9、99、999等。注意:這個元字符不是所有的軟件都支持的。
          ?
          匹配0或1個正好在它之前的那個字符。注意:這個元字符不是所有的軟件都支持的。
          \{i\}
          \{i,j\}
          匹配指定數目的字符,這些字符是在它之前的表達式定義的。例如正則表達式A[0-9]\{3\} 能夠匹配字符"A"后面跟著正好3個數字字符的串,例如A123、A348等,但是不匹配A1234。而正則表達式[0-9]\{4,6\} 匹配連續的任意4個、5個或者6個數字字符。注意:這個元字符不是所有的軟件都支持的。


          posted @ 2006-08-07 17:06 Dave 閱讀(168) | 評論 (0)編輯 收藏
          public aspect TraceAspect{
             private Logger _logger = Logger.getLogger("trace");
             pointcut traceMethods(): execution(* *.*(..))&&!within(TraceAsptect);
             before() : traceMethods(){
                Signature sig = thisJoinPointStaticPart.getSignature();
                _logger.logp(Level.INFO, sig.getDeclaringType().getName(), sig.getName(), "Entering");
            }
          }

          What’s wrong with conventional logging ?

          When a new module is added to the system, all of its methods that need logging must be instrumented. Such instrumentation is invasive, causing the tangling of the core concerns with the logging concern. Further, if you ever happen to change the logging toolkit to a different API, you need to revisit every logging statement and modify it.

          Consistency is the single most important requirement of logging. It means that if the logging specification requires that certain kinds of operations be logged, then the implementation must log every invocation of those operations. When things go wrong in a system, doubting the logging consistency is probably the last thing you want to do. Missed logging calls can make output hard to understand and sometimes useless. Achieving consistency using conventional logging is a lofty goal, and while systems can attain it initially, it requires continuing vigilance to keep it so. For example, if you add new classes to the system or new methods in existing classes, you must ensure that they implement logging that matches the current logging strategy.

          The beauty of AspectJ-based logging

          The limitations are not a result of the logging APIs or their implementations; rather, they stem from the fundamental limitations of objectoriented programming, which require embedding the logging invocations in each module. AOP and AspectJ overcome those limitations. AspectJ easily implements the invocation of logging statements from all the log points. The beauty is that you do not need to actually instrument any log points; writing an aspect does it automatically. Further, since there is a central place to control logging operations, you achieve consistency easily.

          The most fundamental difference between conventional logging and AspectJbased logging is modularization of the logging concern. Instead of writing modules that implement core concepts in addition to invoking logging operations, with AspectJ you write a few aspects that advise the execution of the operations in the core modules to perform the logging. That way, the core modules do not carry any logging-related code. By modularizing, you separate the logging concern
          from the core concerns.

          With AspectJ-based logging, the logger aspect separates the core modules and the logger object. Instead of the core modules’ embedding the log() method invocations in their source code, the logger aspect weaves the logging invocations into the core modules when they are needed. AspectJ-based logging reverses the dependency between the core modules and the logger; it is the aspect that encodes how the operations in the core modules are logged instead
          of each core module deciding for itself.
          posted @ 2005-08-29 10:52 Dave 閱讀(815) | 評論 (2)編輯 收藏
           

          泛型的引入使得 Java 語言中的類型系統更加復雜。以前,該語言具有兩種類型 —— 引用類型和基本類型。對于引用類型,類型 的概念基本上可以互換,術語子類型子類 也可以互換。

          隨著泛型的引入,類型和類之間的關系變得更加復雜。List<Integer>List<Object> 是不同的類型,但是卻是相同的類。盡管 Integer 擴展 Object,但是 List<Integer> 不是 List<Object>,并且不能賦給 List<Object> 或者強制轉換成 List<Object>

          另一方面,現在有了一個新的古怪的類型叫做 List<?>,它是 List<Integer>List<Object> 的父類。并且有一個更加古怪的 List<? extends Number>。類型層次的結構和形狀也變得復雜得多。類型和類不再幾乎是相同的東西了。

          extends 的新含意 

          在 Java 語言引入泛型之前,extends 關鍵字總是意味著創建一個新的繼承自另一個類或接口的類或接口。

          引入泛型之后,extends 關鍵字有了另一個含意。將 extends 用在類型參數的定義中(Collection<T extends Number>)或者通配符類型參數中(Collection<? extends Number>)。

          當使用 extends 來指示類型參數限制時,不需要子類-父類關系,只需要子類型-父類型關系。還要記住,有限制類型不需要是該限制的嚴格子類型;也可以 該限制。換句話說,對于 Collection<? extends Number>,您可以賦給它 Collection<Number>(盡管 Number 不是 Number 的嚴格子類型)和 Collection<Integer>Collection<Long>Collection<Float> 等等。

          在任何這些含意中,extends 右邊的類型都可以是參數化類型(Set<V> extends Collection<V>)。

          posted @ 2005-08-24 11:36 Dave 閱讀(191) | 評論 (0)編輯 收藏
          Eclipse 運行命令行參數大全  
            包括英文版本和中文版本兩種的說明, 特別需要值得一提的是那個 -nl 參數, 可以指定程序啟動時所使用的語言. 例如:
          eclipse -nl en_US
          將啟動英文語言, 這個特性在安裝了國際化語言包以后特別有用, 可以方便的切換各個語言的版本. 注意 IBM WSAD v5.1 也支持這個功能. 

          運行 Eclipse
          將 Eclipse 驅動程序安裝(解壓縮)到某個目錄(例如,c:\eclipse)中之后,通過運行頂級安裝目錄中的 Eclipse 可執行文件來啟動"工作臺"。在 Windows 系統上,該可執行文件稱為 eclipse.exe,而在 Linux 系統上稱為 eclipse。注意:下列討論描述 Windows 系統上的設置。Linux 上的設置是相似的。

          如果您沒有另行指定,則平臺將缺省工作區目錄創建為可執行文件的兄弟目錄(例如 c:\eclipse\workspace)。此工作區目錄用作項目的缺省內容區,還用于保存任何必需的元數據。要進行共享安裝或多工作區安裝,應明確指出工作區的位置而不是使用缺省值。有兩種控制工作區位置的方法:使用當前工作目錄或使用 -data 命令行自變量。

          將工作區位置設置為在當前工作目錄內
          在此方案中,工作區位置將是當前工作目錄中稱為 workspace 的目錄。

          實現此目的最容易的方法可能是使用下列步驟來創建快捷方式:

          導航到 Windows 資源管理器中的 eclipse.exe 并使用右鍵拖動來創建 eclipse.exe 的快捷方式。 
          編輯快捷方式的屬性,以使啟動位置:字段標識工作區位置的父目錄(例如,c:\users\robert)。 
          關閉屬性對話框并雙擊快捷方式(如果提供的目錄為 c:\users\robert,則工作區位置將為 c:\users\robert\workspace)。 
          當然,您也可以使用命令提示符(通過將目錄切換為工作區父目錄然后運行 eclipse.exe)來獲得同樣的效果。

          使用 -data 設置工作區的特定位置
          要使用 -data 命令行自變量,只要將 -data your_workspace_location(例如,-data c:\users\robert\myworkspace)添加至快捷方式屬性中的目標字段或顯式地將它包括在命令行上。

          使用 -vm 設置 java VM
          建議顯式指定在運行 Eclipse 時要使用哪個 Java VM。使用 -vm 命令行自變量(例如,-vm c:\jre\bin\javaw.exe)可以實現此目的。如果不使用 -vm,則 Eclipse 將使用在 O/S 路徑上找到的一個 Java VM。當安裝其它產品時,它們可更改您的路徑,導致在下一次啟動 Eclipse 時使用另一 Java VM。

          運行 Eclipse 中的高級主題
          Eclipse 可執行文件及平臺本身提供了人們感興趣的開發或調試 Eclipse 各部件的許多執行選項。運行 Eclipse 可執行文件的一般格式是:

          eclipse [platform options] [-vmargs [Java VM arguments]]
          Eclipse 啟動參數  命令 描述  原因 
          -arch architecture
           定義 Eclipse 平臺在其上運行的處理器體系結構。Eclipse 平臺通常使用 Java os.arch 屬性的常用值來計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getOSArch() 用于插件。示例值有:"x86"、"sparc"、"PA-RISC"和"ppc"。 2.0 
          -application applicationId
           要運行的應用程序。應用程序由向 org.eclipse.core.runtime.applications 擴展點提供擴展的插件來聲明。通常不需要此自變量。如果指定了此項,則該值會覆蓋配置提供的值。如果不指定此項,則會運行"Eclipse 工作臺"。 1.0 
          -boot bootJarURL
           (建議不使用;用 -configuration 代替;支持 1.0 兼容)。Eclipse 平臺的引導插件代碼(boot.jar)的位置,表示為 URL。如果指定此項,則會用它來為裝入 Eclipse 平臺引導程序類裝入器的類裝入器設置類路徑。僅當更改 startup.jar 和 boot.jar 的相對位置時才需要它。注意,不允許使用相對 URL。  *1.0 
          -classloaderproperties [file]
           如果指定的話,則使用給定位置處的類裝入器屬性文件來激活平臺類類裝入器增強。文件自變量可以是文件路徑或 URL。注意,不允許使用相對 URL。單擊此處以獲得更多詳細信息。 2.0.2 
          -configuration configurationFileURL
           Eclipse 平臺配置文件的位置,表示為 URL。配置文件確定 Eclipse 平臺、可用插件集和主要功能部件的位置。注意,不允許使用相對 URL。當安裝或更新 Eclipse 平臺時配置文件被寫至此位置。  2.0 
          -consolelog
           將 Eclipse 平臺的錯誤日志鏡像到用來運行 Eclipse 的控制臺。與 -debug 組合時很方便使用。 1.0 
          -data workspacePath
           要運行 Eclipse 平臺的工作區的路徑。工作區位置也是項目的缺省位置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0 
          -debug [optionsFile]
           將平臺置于調試方式,并從給定位置處的文件裝入調試選項(如果指定的話)。此文件指示哪些調試點可用于插件以及是否已啟用它們。如果未給出文件位置,則平臺在啟動 eclipse 的目錄中查找稱為".options"的文件。URL 和文件系統路徑都可作為文件位置。 1.0 
          -dev [classpathEntries]
           將平臺置于開發方式。將可選類路徑條目(用逗號分隔的列表)添加至每個插件的運行時類路徑。例如,當工作區包含要開發的插件時,指定 -dev bin 會為每個插件項目的名為 bin 的目錄添加類路徑條目,允許在其中存儲最新生成的類文件。除去了冗余或不存在的類路徑條目。 1.0 
          -endsplash params
           用于在 Eclipse 平臺啟動并運行時關閉閃屏的內部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0 
          -feature featureId
           主要功能部件的標識。主要功能部件為 Eclipse 的已啟動實例提供了產品個性,并確定使用的產品定制信息。 2.0 
          -keyring keyringFilePath
           磁盤上授權數據庫(或"密鑰環"文件)的位置。此自變量必須與 -password 選項配合使用。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0 
          -nl locale
           定義 Eclipse 平臺在其上運行的語言環境的名稱。Eclipse 平臺通常自動計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getNL() 用于插件。示例值有:"en_US"和"fr_FR_EURO"。 2.0 
          -nolazyregistrycacheloading
           取消激活裝入優化的平臺插件注冊表高速緩存。缺省情況下,僅當需要時才從注冊表高速緩存(可用時)中裝入擴展的配置元素,以減少內存占用。此選項將在啟動時強制完全裝入注冊表高速緩存。 2.1 
          -noregistrycache
           繞過讀寫內部插件注冊表高速緩存文件。 2.0 
          -nosplash
           運行平臺而不顯示閃屏。 1.0 
          -os operatingSystem
           定義 Eclipse 平臺在其上運行的操作系統。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getOS() 用于插件,并用于解析插件清單文件中提及的路徑中 $os$ 變量的出現。示例值有:"win32"、"linux"、"hpux"、"solaris"和"aix"。 1.0 
          -password password
           授權數據庫的密碼。與 -keyring 選項配合使用。 1.0 
          -perspective perspectiveId
           啟動時要在活動工作臺窗口中打開的透視圖。如果沒有指定該參數,則將打開關閉時活動的透視圖。 1.0 
          -plugincustomization   propertiesFile
           包含插件首選項缺省設置的屬性文件的位置。這些缺省設置覆蓋在主要功能部件中指定的缺省設置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 2.0 
          -plugins pluginsFileURL
           (建議不使用;用 -configuration 代替;支持 1.0 兼容)。 指定 Eclipse 平臺查找插件的文件的位置,表示為 URL。該文件為屬性文件格式,其中鍵是任意用戶定義名稱,值是指向 plugin.xml 文件的顯式路徑或指向包含插件的目錄的路徑的用逗號分隔的列表。注意,不允許使用相對 URL。如果指定此項,則此選項會導致創建適當的臨時配置。 *1.0 
          -refresh 
           啟動時執行工作區的全局刷新的選項。這將使從上次平臺運行以來在文件系統中所做的任何更改一致。 1.0 
          -showlocation 
           用于在窗口標題欄中顯示工作區的位置的選項。在發行版 2.0 中,此選項僅與 -data 命令行自變量一起使用。 2.0 
          -showsplash params
           用于顯示閃屏(由可執行的 Eclipse 平臺啟動器執行)的內部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0 
          -vm vmPath
           要用來運行 Eclipse 平臺的"Java 運行時環境"(JRE)的位置。如果不指定此項,則 JRE 位于 jre(它是 Eclipse 可執行文件的兄弟目錄)。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0 
          -ws windowSystem
           定義 Eclipse 平臺在其上運行的 Windows 系統。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getWS() 用于插件、用于配置 SWT 以及用于解析插件清單文件中提及的路徑中 $ws$ 變量的出現。示例值有:"win32"、"motif"和"gtk"。 1.0 

          將 -vmargs 條目后面的所有自變量(但不包括 -vmargs)作為虛擬機自變量(即,在要運行的類的前面)直接傳遞到所指示的 Java VM。注意:如果 Eclipse 啟動在 Java vm 自變量(-vmargs)之后提供的自變量(例如,-data),則 Eclipse 將不會啟動并且您將接收到"JVM 已終止。出口代碼為 1"的錯誤。

          在不同的 VM 上運行 
          在 J9 上運行 Eclipse
          當在 J9 版本 1.5 上運行 Eclipse 時,建議使用以下 VM 選項: 

          eclipse.exe [eclipse arguments] -vm path_to_j9w.exe             -vmargs -ms:32 -mm:2048 -mo:32768 -moi:32768 -mca:32 -mco:128 -mx:2000000
          當在 J9 版本 2.0 上運行 Eclipse 時,J9W 選擇的缺省自變量應為合適的選項。但是,要覆蓋 Eclipse 可執行文件以內部方式自動設置的參數,必須指定 -vmargs 不帶任何參數,如下所示: 

          eclipse.exe [eclipse arguments] -vm path_to_j9w.exe -vmargs
          有關進一步信息,參考 J9 VM 文檔和幫助。

          在 IBM Developer Kit, Java(TM) Technology Edition VM 上運行 Eclipse
          IBM Developer Kit, Java(TM) Technology Edition 1.3 Linux 的缺省 VM 設置適合進行初期研究工作,但在進行大型開發時是不夠的。對于大型開發,應修改 VM 自變量以使有更多的堆可用。例如,下列設置將允許 Java 堆增大為 256MB:
          posted @ 2005-08-22 10:49 Dave 閱讀(215) | 評論 (0)編輯 收藏
          愛因斯坦曾經說:“任何事情都應該越簡單越好,而不是比較簡單。”實際上,科學真理的目的就是在假設的前提下去簡化一個理論,這樣,人們可以去關注真正重要的問題。在企業軟件開發中,道理是一樣的。
            簡化企業軟件開發的一個關鍵是,提供一個這樣的應用框架:它可以使開發人員不用關注于很多復雜的問題,比如事務處理、安全和持久化等。一個設計良好的框架將提升代碼的可復用性,提高開發者的效率,并得到更高質量的軟件。然而,目前J2EE 1.4下的EJB 2.1 框架被廣泛認為是設計較差而且過度復雜的。不滿足于EJB2.1框架,JAVA開發者使用了很多其他的中間件服務產品。最值得關注的是,以下兩個框架吸引了大量開發者的興趣和積極反饋。這兩個框架很可能成為未來企業JAVA應用開發框架的選擇。
            Spring框架是一個廣受歡迎的但是非標準的開源框架。它主要由Interface21公司開發和控制。Spring框架的體系結構是基于注射依賴(DI)模式。Spring框架使用了大量的XML配置文件,它可以獨立應用,或者在現有的應用服務器上工作。
            EJB 3.0框架是JCP定義的并且被所有主流J2EE提供商支持的標準框架。EJB 3.0規范的預發布版本目前已經有開源的和商業的實現,如JBOSS和ORACLE。EJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能。譯者注)
            這兩個框架有著一個共同的核心設計理念:它們的目標是為松耦合的POJO類提供中間件服務。框架通過在運行時截取執行環境,或將服務對象注射給POJO類的方式,將應用服務和POJO類“連接”起來。POJO類本身并不關注如何“連接”,而且也很少依賴于框架。這樣,開發者可以將注意力集中在業務邏輯上,可以對他們的POJO類進行與框架無關的單元測試。并且,由于POJO類不需要繼承框架的類或實現框架提供的接口,開發者可以在更加靈活性的基礎上構建繼承體系,和搭建應用。
            盡管有著共同的理念,但這兩個框架采取了不同的方式來提供POJO服務。由于已經出版了大量的比較Spring與EJB2.1或者EJB3.0與EJB2.1的書籍和文章,而沒有關于比較Spring和EJB3.0的認真研究,因此,本文將考察它們之間幾個關鍵的不同,討論他們優缺點。本文談到的主題同樣適用于其他不太有名的但同樣提供“松耦合POJO” 設計的企業中間件框架。我希望,這篇文章可以幫助你選者最合適的你需求的框架。
          提供商無關性
            開發者選擇JAVA平臺的一個最重要的原因就是它的提供廠商無關性。EJB 3.0是一個被設計為對提供商沒有依賴性的開放的標準。EJB 3.0規范由企業JAVA社區的主流開源組織和廠商共同編寫和支持的。EJB 3.0框架使開發者的應用程序實現可以獨立于應用服務器。比如,JBoss的EJB 3.0的實現是基于Hibernate的,Oracle的EJB 3.0實現是基于TopLink的,但是,在JBoss或者Oracle上跑應用程序,開發者既不需要去學習Hibernate,也不需要學習TopLink提供的獨特API。廠商無關性使EJB 3.0框架區別于當前其他任何的POJO中間件框架。
            然而,就象很多EJB 3.0的批評者很快指出的一樣,目前EJB 3.0規范正在編寫還未完全完成最終發布版。很有可能,還需要1至2年,EJB 3.0才會被主流J2EE廠商完全接受。但是,就算你的應用服務器本身不支持EJB 3.0,你也可以通過下載和安裝一個“可嵌入的” EJB 3.0產品,來使你的應用服務器支持EJB 3.0應用。比如,JBoss“可嵌入的” EJB 3.0產品是開源的,它可以運行在任何兼容J2SE-5.0環境下(如你的應用服務器),目前處于Beta版測試中。其他廠商同樣可以快速發布他們自己的可嵌入EJB 3.0產品,特別是規范中“數據持久化”部分。
            另一方面,Spring一直是一個非標準的技術,而且在可以預計的未來仍將如此。盡管你在任何應用服務器都上可以使用Spring框架,但基于Spring的應用仍然被限制于Spring本身和在你的應用中使用到的Spring提供的各種特別服務。
            由于Spring框架是一個開源項目,因此,它使用的配置文件XML格式和開發接口都是私有的。當然,這種限制不僅體現在Spring框架中,其他任何非標準產品都會有這種限制。但是,你的Spring應用的長期生存能力將依賴于Spring項目本身(或者說Interface 21公司,因為它雇傭了大多數的Spring核心開發人員)。并且,如果你使用了Spring提供的特殊服務,如Spring事務管理器或者Spring MVC,你同樣被限制于Spring提供的API。
            并且,Spring應用是知道后端服務提供者的(即應用程序是知道服務提供者的,這樣應用程序將會在一定程度上依賴于服務提供方:譯者注)。例如,對于數據持久化服務,Spring框架提供了不同的DAO和模板Helper類,用于JDBC、Hibernate,、iBatis和JDO。這樣,假如你需要改變一個Spring應用的持久化服務提供者(如,從JDBC換到Hibernate),你將需要重構你的系統應用代碼,來使用新的Helper類。
          服務整合
            Spring框架是建立在應用服務器和服務庫之上,它的服務整合代碼(如數據訪問模板和Helper類)是基于框架的,并暴露給應用開發者。相反,EJB 3.0框架是緊密整合到應用服務器中的,它的服務整合代碼是封裝在一個標準的接口下的。
            因此,EJB 3.0廠商可以輕松的優化整體性能和開發者體驗。如,在JBoss的EJB 3.0實現中,當你通過實體管理器持久化一個實體BEAN POJO時,Hibernate session事務將在JTA事務提交時自動提交。通過使用簡單的@PersistenceContext注解(例子參看后面文章),你可以甚至可以將實體管理器和其下的Hibernate事務綁定到一個有狀態的session bean上。應用程序事務可以在一個session中跨越多個線程,在事務性的WEB應用中這是非常有用的,如多頁面的購物車。
            基于EJB 3.0 框架、Hibernate、和JBoss 內部Tomcat的緊密整合,上面提到的簡單的整合的編程接口是可能的。Oracle的EJB 3.0框架和它內部的Toplink持久服務可以達到同樣層次的整合。
            EJB 3.0中整合服務的另一個好例子是集群支持。假如你部署一個EJB 3.0應用到一個集群服務器,所有的故障切換、負載均衡、分布式緩存、和狀態復制服務對于應用程序來說,都是自動完成的。集群服務被隱藏在EJB 3.0編程接口之下,對于EJB 3.0開發者來說,這些服務都是完全透明的。
            在Spring中,優化框架和服務之間交互更加困難一些。例如,想要用Spring的聲明式事務服務來管理Hibernate事務,必須在XML配置文件中明確的配置Spring的事務管理器(TransactionManager)和Hibernate SessionFactory對象。Spring應用開發者必須自己管理跨越多個HTTP請求的事務。并且,沒有簡單的方法可以在Spring應用中實現集群服務
          服務聚合的靈活性
            由于Spring中的服務整合代碼是作為編程接口暴露給應用開發者的,因此開發人員可以根據需要來聚合多個服務。這個特性使你可以集成一個你自己的“輕量”級應用服務器。Spring的一個通常的用法是將Tomcat和Hibernate連接起來來支持簡單的數據庫驅動的WEB應用程序。在這種情況下,Spring本身提供了事務管理服務,Hibernate提供了持久化服務,這種設置本身就創建了一個小型的應用服務器。
            通常,EJB 3.0應用服務器不提供給開發者這種按照你的需要來選擇服務的靈活性。大多數情況,你會得到一系列已經預先打包好的特性,其中有些你可能是不需要的。然而,如果應用服務器提供了模塊內部的獨特設計,就象JBOSS一樣,你可以不去關心這些不必要的特性。在任何情況下,去定制一個全功能的應用服務器并不是一個瑣碎而沒有意義的工作。
            當然,如果一個應用不是一個單一的結點,你將需要連接多個應用服務器提供的服務(如資源池、消息隊列和集群)。這種情況下,從總的資源消耗上看,Spring框架就和任何EJB 3.0方案一樣是“重量級”的。
            為了進行容器外的單元測試,Spring的靈活的服務聚合也可以來連接假對象,來替代真的服務對象。在EJB 3.0應用中,大多數的組件都是簡單POJO,他們可以容易進行容器外的單元測試。但是,如果要測試與容器服務相關的服務對象(如持久化實體管理器),更好的方式是進行容器內的測試,因為這樣比使用假對象來替代的方式更加容易,更加健壯,而且更加準確。
          XML vs. 注解
            從應用開發者的角度來看,Spring的編程接口主要基于XML配置文件,而EJB 3.0則大量的使用了JAVA注解。XML文件可以表達復雜的關系,但是它們更加冗長而且不健壯。注解的方式很簡單明了,但是很難去表達復雜的或者繼承性的結構。
            Spring和EJB 3.0分別選擇了XML和注解方式,這取決于框架的體系結構:由于注釋只能描述相當少的配置信息,只有一個預先整合好的框架(如大多數重要事情已經在框架中實現了)才能大量的使用注釋作為它的配置選項。象我們討論的一樣,EJB 3.0滿足了這些要求,而Spring作為一個一般的注射依賴框架,它沒有做到這一點。
            當然,由于EJB 3.0和Spring相互學習了很多特性,所以,它們都在某種層次上支持XML和注釋。例如,EJB 3.0中可以應用XML配置文件來作為一個選擇性的機制,用來改變注釋的默認行為。注釋也可以用來配置一些Spring服務。
            研究XML和注釋直接區別的最好的方式就是通過例子。在下面的幾節中,我們將一起看一下EJB 3.0和Spring是如何為應用程序提供關鍵服務的。
          聲明式服務
            EJB 3.0和Spring都將運行時服務(如事務管理、安全、日志、消息、和信息服務)連接給應用程序。由于這些服務同應用程序的業務邏輯并不是直接相關的,因此,它們不被應用程序本身來管理。相反,這些服務被服務容器(如EJB 3.0和Spring)以不可見的方式在運行時提供給應用程序。開發人員(或系統管理員)通過配置來告訴容器什么時候,以怎樣的方式來應用這些服務。
            EJB 3.0通過JAVA注解的方式來配置聲明式服務,Spring則通過XML配置文件來完成。大多數情況下,EJB 3.0 的注解方式是應用這種服務的更加簡單和優美的方式。下面是一個在EJB 3.0中對一個POJO的方法使用事務管理服務的例子。
            public class Foo {
                @TransactionAttribute(TransactionAttributeType.REQUIRED)
                public bar () {
                  // do something ...
                }   
            }
            你可以對一段代碼聲明多個屬性,并應用多個服務。下面是一個對EJB 3.0中POJO類同時使用事務管理服務和安全服務的例子。
            @SecurityDomain("other")
            public class Foo {
                @RolesAllowed({"managers"})
                @TransactionAttribute(TransactionAttributeType.REQUIRED)
                public bar () {
                  // do something ...
                }  
            }
            使用XML指定代碼屬性和配置聲明服務將導致冗長的和不桅頂的配置文件。下面是Spring應用中一個XML元素的例子,它用來在Foo.bar()方法上應用一個非常簡單的Hibernate事務。
          <!-- Setup the transaction interceptor -->
          <bean id="foo"
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
              <property name="target">
                  <bean class="Foo"/>
              </property>
              <property name="transactionManager">
                  <ref bean="transactionManager"/>
              </property>
              <property name="transactionAttributeSource">
                  <ref bean="attributeSource"/>
              </property>
          </bean>
          <!-- Setup the transaction manager for Hibernate -->
          <bean id="transactionManager"
            class="org.springframework.orm.hibernate.HibernateTransactionManager">
              <property name="sessionFactory">
                  <!-- you need to setup the sessionFactory bean in yet another XML element -->
                  <ref bean="sessionFactory"/>
              </property>
          </bean>
          <!-- Specify which methods to apply transaction -->
          <bean id="transactionAttributeSource"
          class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
              <property name="properties">
                  <props>
                      <prop key="bar">
                  </props>
              </property>
          </bean>
            XML文件的復雜程度將隨著你對同一個POJO類增加的攔截器的數量程幾何增長。意識到了僅使用XML配置文件的限制性,Spring支持在JAVA源代碼中使用Apache Commons metadata來指定事物屬性。在最新的Spring 1.2中,JDK-1.5風格的注釋也被支持。為了使用事務元數據,你需要為上面例子中的AttributesTransactionAttributeSource 改變一個transactionAttributeSource bean,并且增加一個附加的對元數據攔截器的設置。
          <bean id="autoproxy"
           class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
          <bean id="transactionAttributeSource"
            class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource"
              autowire="constructor"/>
          <bean id="transactionInterceptor"
              class="org.springframework.transaction.interceptor.TransactionInterceptor"
              autowire="byType"/>
          <bean id="transactionAdvisor"
              class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
              autowire="constructor"/>
          <bean id="attributes"
          class="org.springframework.metadata.commons.CommonsAttributes"/>
            
            當你有許多事務方法時,Spring元數據簡化了transactionAttributeSource元素。但是它沒有解決XML配置文件的根本問題:仍然需要冗長的、易錯的事務攔截器,事務管理器,和事務屬性。
          注射依賴
            中間件容器的一個主要優點是它們使得程序開發人員可以去構建松耦合的應用程序。服務使用者僅僅需要知道服務接口就可以使用服務。容器把具體的服務實現實例化,然后將它們提供給服務使用者。這樣,容器可以在可替換的服務實現之間進行切換,而不改變服務接口和服務使用者代碼。
            注射依賴模式是實現松耦合應用程序的一個最好的方式。比起以前的方式,如通過JNDI進行查找或回調容器,注射依賴模式更容易使用,而且更加優美。使用注射依賴模式,框架扮演了構建服務的對象工廠角色,然后根據運行時的配置,把這些服務對象注射到應用程序的POJO類中。從程序開發人員的角度看,作為客戶端使用者的POJO在需要使用服務對象前就自動的得到了它們。
            Spring 和 EJB 3.0都提供了大量的DI模式支持。但是,它們之間也有著根本的不同。Spring支持了通常意義上的但是復雜的基于XML配置文件的注射依賴API;EJB 3.0支持的注射大多數通用服務對象(如,EJB和容器對象)和JNDI對象,它通過簡單的JAVA注解來完成。
            EJB 3.0的注射注解相當的簡潔易用。@Resource標簽注射大多數的通過服務對象和JNDI對象。下面的例子顯示了如何將JNDI提供的服務器缺剩數據源對象注射給一個POJO的一個字段。DefaultDS是這個數據源的JNDI名字。myDb 變量在第一次被使用前就自動被賦予了正確的值。
            public class FooDao {
                @Resource (name="DefaultDS")
                DataSource myDb;
                // Use myDb to get JDBC connection to the database
            }
            在EJB 3.0中,注釋@Resource不僅可以直接注射給屬性變量,它也可以通過setter方法來完成注射。下面的例子將一個session上下文對象通過setter方法注射給使用者。應用程序不用顯示的調用setter方法,在任何其他方法被調用前容器將調用setter方法完成注射。
            @Resource
            public void setSessionContext (SessionContext ctx) {
                sessionCtx = ctx;
            }
            對于更復雜的服務對象,還有一些特殊的注射注解。例如,@EJB 注解被用來注射EJB stubs,@PersistenceContext注解被用來注射實體管理器對象,這些對象負責處理EJB 3.0實體Bean的數據訪問操作。 下面的例子給出如何將一個實體管理器注射到一個有狀態Session Bean中。@PersistenceContext注解的類型屬性描述了被注射的的實體管理器有一個擴展的事務容器:它不會隨著JTA事務管理器自動提交事務,因此它可以應用在當session中有多次操作的應用事務管理時。
            @Stateful
            public class FooBean implements Foo, Serializable {
                @PersistenceContext(
                  type=PersistenceContextType.EXTENDED
                )
                protected EntityManager em;
                public Foo getFoo (Integer id) {
                    return (Foo) em.find(Foo.class, id);
                }
            }

            EJB 3.0 規范定義了可以通過注解來被注射使用的服務器資源。但是,它不支持用戶自定義的POJO類之間的相互注射。
            在Spring中,為了將服務對象注射到你的POJO類中,你首先需要定義一個setter方法(或有參數的構造函數) 。下面的例子演示了 POJO 類中一個Hibernate session 工廠的屬性。
            public class FooDao {
                HibernateTemplate hibernateTemplate;
                public void setHibernateTemplate (HibernateTemplate ht) {
                    hibernateTemplate = ht;
                }
                // Use hibernateTemplate to access data via Hibernate
                public Foo getFoo (Integer id) {
                    return (Foo) hibernateTemplate.load (Foo.class, id);
                }
            }
            因此,你可以指定容器如何得到這個服務,并且在運行時通過配置文件中XML元素的連接關系把它提供給POJO。下面的例子顯示了連接一個數據源到一個Hibernate session 工廠、session 工廠到Hibernate模板對象、模板對象最后到應用程序POJO類,整個過程的XML配置。
            Spring 代碼復雜性的部分原因是,我們需要手工的去注射Hibernate相關類,然而,EJB 3.0 實體管理器被服務器自動管理和配置。但是,這使我們返回到了這樣的討論:Spring 不象EJB 3.0 一樣,它不同服務緊密整合在一起。
          <bean id="dataSource"
            class="org.springframework.jndi.JndiObjectFactoryBean">
              <property name="jndiname">
                  <value>java:comp/env/jdbc/MyDataSource</value>
              </property>
          </bean>
          <bean id="sessionFactory"
            class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
              <property name="dataSource">
                  <ref bean="dataSource"/>
              </property>
          </bean>
          <bean id="hibernateTemplate"
            class="org.springframework.orm.hibernate.HibernateTemplate">
              <property name="sessionFactory">
                  <ref bean="sessionFactory"/>
              </property>   
          </bean>
          <bean id="fooDao" class="FooDao">
              <property name="hibernateTemplate">
                  <ref bean="hibernateTemplate"/>
              </property>
          </bean>
          <!-- The hibernateTemplate can be injected into more DAO objects -->
            盡管Spring中基于XML的注射依賴比較復雜,但是它非常強大。你可以注射任何POJO到另外的POJO中,包括程序中自定義的。
            如果你確實想在EJB 3.0應用中使用Spring的注射依賴功能,你可以將一個Spring Bean工廠類通過JNDI注射到一個EJB中。在某些EJB 3.0 應用服務器中,廠商可能會定義一些非標準的API用來注射任意的POJO類。一個很好的例子是JBoss MicroContainer,它處理了AOP依賴性,因此它是甚至比Spring 更加通用。
            
          結論
            盡管Spring 和EJB 3.0的目標都是提供企業服務,使得POJO可以松耦合,但是它們實現的方式非常不同。在兩個框架中注射依賴模式都有大量的應用。
            通過EJB 3.0的標準方式、大量應用的注解、還有同應用服務器緊密整合性,這些提供了更高的廠商無關性和開發人員工作效率。Spring的以XML為中心的配置文件和注射依賴的連貫使用,允許開發人員去構造更加靈活的應用系統,并且可以同時與多個應用服務提供者同時工作。
            
          感謝
           
           作者感謝Stephen Chambers, Bill Burke, 和Andy Oliver 的有價值的評論.
          參考
            The Spring framework (參考CodeZoo: Spring)
          EJB 3.0
          JBoss EJB 3.0
          Oracle Application Server EJB 3.0 Preview
          Michael Juntao Yuan specializes in end-to-end enterprise solutions and is a mobile geek and avid open source supporter.


          posted @ 2005-08-22 10:13 Dave 閱讀(227) | 評論 (0)編輯 收藏
          ?? bsh-deployer:將BeanShell腳本部署成JBoss服務。
          ?? cache-invalidation-service.xml:允許借助于JMS,而實現對EJB緩存的控制。
          ?? client-deployer-service.xml:部署J2EE應用客戶。
          ?? ear-deployer.xml:部署J2EE EAR應用。
          ?? ejb-deployer.xml:部署J2EE EJB應用。
          ?? hsqldb-ds.xml:設置嵌入式Hypersonic數據庫服務,并將其作為默認數據源。
          ?? http-invoker.sar:通過RMI/HTTP方式訪問到MBean和EJB。
          ?? jboss-aop.deployer:提供AspectManagerService,并部署JBoss AOP應用。
          ?? jboss-hibernate.deployer:部署Hibernate存檔(HAR文件)。
          ?? jboss-local-jdbc.rar和jboss-xa-jdbc.rar:集成JDBC驅動的JCA資源適配器,它們分別支持DataSource和XADataSource。但是,這并沒有提供專有JCA實現。
          ?? jboss-ws4ee.sar:提供J2EE Web服務支持。
          ?? jbossjca-service.xml:JBoss JCA實現,使得在JBoss中部署JCA資源適配器成為可能。
          ?? jbossweb-tomcat50-sar:含有嵌入式Tomcat服務的展開SAR文件。它為JBoss提供了標準的Web容器。
          ?? jms:將JMS相關的服務聚集在一起,并放置在jms目錄中。
          ?? hsqldb-jdbc-state-service.xml:使用HSQLDB管理狀態。
          ?? hsqldb-jdbc2-service.xml:使用嵌入式HSQL數據庫實現緩存和持久化。它還包含了JMS實現的核心服務,即DestinationManager MBean。
          ?? jbossmq-destinations-service.xml:供JBoss測試套件使用的JMS Topic和Queue。
          ?? jbossmq-service.xml:JMS其他服務,包括攔截器配置。
          ?? jms-ds.xml:將JBoss消息實現作為默認JMS提供商。并且,它還提供JCA配置信息,以供集成JBoss JCA和JMS資源適配器使用。
          ?? jms-ra.rar:資源適配器,供JCA處理JMS連接工廠使用。
          ?? jbossmq-httpil.sar:提供JMS調用層,從而實現HTTP方式使用JMS。
          ?? jvm-il-service.xml:配置本地JMS傳輸調用層,供本地JVM使用JMS。
          ?? uil2-service.xml:配置JMS版本2統一調用層。這是一種可靠的、自定義的、基于Socket的傳輸方式。推薦在不同JVM間使用它。
          ?? jmx-console.war:JMX控制臺應用。前面討論過。
          ?? jmx-invoker-server.xml:為遠程訪問JMX MBean服務器提供支持。
          ?? mail-ra.rar:為JavaMail提供資源適配器。
          ?? mail-service.xml:允許應用和服務在JBoss中使用JavaMail。請注意,郵件服務器相關信息必須由用戶提供。
          ?? management:含有可更換管理服務的子目錄。其中,包含有改進的Web控制臺。
          ?? monitoring-service.xml:配置警告監聽器,比如控制臺監聽器、E_mail監聽器,等等。
          ?? properties-service.xml:設置JVM的全局系統屬性(由System.getProperties返回)。
          ?? schedule-manager-service.xml和scheduler-service.xml:定時任務服務。
          ?? sqlexception-service.xml:為JDBC驅動提供標識一般性SQL異常。
          ?? uuid-key-generator.sar:生成唯一的、基于UUID的鍵。
          all配置提供了其他配置沒有提供的其他服務,用戶可以將這些服務集成到各自的服務器配置中。具體如下:
          ?? cluster-service.xml:群集服務,包括JGroups集成服務、HA-JNDI、有狀態會話Bean復制、CMP2緩存有效性服務。
          ?? deploy-hasingleton-service.xml:HASingletonDeployer MBean。用于確保群集中只有單個節點在deploy-hasingleton目錄部署了服務。
          ?? deploy.last/farm-service.xml:farm群集部署服務。用于確保它在所有其他服務部署之后才部署其本身。
          ?? ebxmlrr-service.xml:JAXR注冊服務實現。
          ?? iiop-service.xml:實現對CORBA、IIOP的支持。
          ?? jbossha-httpsession.sar:遺留的HTTP會話復制服務。
          ?? remoting-service.xml:還處于試驗中的下一代分離式Invoker框架。
          ?? snmp-adaptor.sar:將JMX通知轉換成SNMP陷阱。
          ?? tc5-cluster-service.xml:用于新的HTTP復制服務的TressCache配置。
          posted @ 2005-08-22 09:25 Dave 閱讀(1208) | 評論 (1)編輯 收藏
          主站蜘蛛池模板: 南皮县| 调兵山市| 紫云| 高雄市| 响水县| 丹凤县| 桂阳县| 二连浩特市| 岳普湖县| 莆田市| 濮阳市| 楚雄市| 微博| 定结县| 融水| 密云县| 馆陶县| SHOW| 景洪市| 石棉县| 鄂州市| 阿拉善左旗| 嘉祥县| 冀州市| 深水埗区| 峨眉山市| 商城县| 延长县| 汉寿县| 庆元县| 勐海县| 苏尼特左旗| 麦盖提县| 德州市| 日土县| 柏乡县| 宿松县| 长岛县| 枝江市| 淮滨县| 团风县|