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) |
編輯 收藏
定義:一個正則表達(dá)式,就是用某種模式去匹配一類字符串的一個公式。
正則表達(dá)式由一些普通字符和一些
元字符(metacharacters)組成。普通字符包括大小寫的字母和數(shù)字,而元字符則具有特殊的含義,我們下面會給予解釋。
元字符 | ? | 描述 |
---|
| |
|
. | | 匹配任何單個字符。例如正則表達(dá)式r.t匹配這些字符串:rat、rut、r t,但是不匹配root。? |
$ | | 匹配行結(jié)束符。例如正則表達(dá)式weasel$ 能夠匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。? |
^ | | 匹配一行的開始。例如正則表達(dá)式^When in能夠匹配字符串"When in the course of human events"的開始,但是不能匹配"What and When in the"。 |
* | | 匹配0或多個正好在它之前的那個字符。例如正則表達(dá)式.*意味著能夠匹配任意數(shù)量的任何字符。 |
\ | | 這是引用府,用來將這里列出的這些元字符當(dāng)作普通的字符來進(jìn)行匹配。例如正則表達(dá)式\$被用來匹配美元符號,而不是行尾,類似的,正則表達(dá)式\.用來匹配點(diǎn)字符,而不是任何字符的通配符。 |
[ ]? [c1-c2] [^c1-c2] | | 匹配括號中的任何一個字符。例如正則表達(dá)式r[aou]t匹配rat、rot和rut,但是不匹配ret??梢栽诶ㄌ栔惺褂眠B字符-來指定字符的區(qū)間,例如正則表達(dá)式[0-9]可以匹配任何數(shù)字字符;還可以制定多個區(qū)間,例如正則表達(dá)式[A-Za-z]可以匹配任何大小寫字母。另一個重要的用法是“排除”,要想匹配除了指定區(qū)間之外的字符——也就是所謂的補(bǔ)集——在左邊的括號和第一個字符之間使用^字符,例如正則表達(dá)式[^269A-Z] 將匹配除了2、6、9和所有大寫字母之外的任何字符。 |
\< \> | | 匹配詞(word)的開始(\<)和結(jié)束(\>)。例如正則表達(dá)式\<the能夠匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:這個元字符不是所有的軟件都支持的。 |
\( \) | | 將 \( 和 \) 之間的表達(dá)式定義為“組”(group),并且將匹配這個表達(dá)式的字符保存到一個臨時區(qū)域(一個正則表達(dá)式中最多可以保存9個),它們可以用 \1 到\9 的符號來引用。 |
| | | 將兩個匹配條件進(jìn)行邏輯“或”(Or)運(yùn)算。例如正則表達(dá)式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:這個元字符不是所有的軟件都支持的。 |
+ | | 匹配1或多個正好在它之前的那個字符。例如正則表達(dá)式9+匹配9、99、999等。注意:這個元字符不是所有的軟件都支持的。 |
? | | 匹配0或1個正好在它之前的那個字符。注意:這個元字符不是所有的軟件都支持的。 |
\{i\} \{i,j\} | | 匹配指定數(shù)目的字符,這些字符是在它之前的表達(dá)式定義的。例如正則表達(dá)式A[0-9]\{3\} 能夠匹配字符"A"后面跟著正好3個數(shù)字字符的串,例如A123、A348等,但是不匹配A1234。而正則表達(dá)式[0-9]\{4,6\} 匹配連續(xù)的任意4個、5個或者6個數(shù)字字符。注意:這個元字符不是所有的軟件都支持的。 |
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 語言中的類型系統(tǒng)更加復(fù)雜。以前,該語言具有兩種類型 —— 引用類型和基本類型。對于引用類型,類型 和類 的概念基本上可以互換,術(shù)語子類型 和子類 也可以互換。
隨著泛型的引入,類型和類之間的關(guān)系變得更加復(fù)雜。List<Integer>
和 List<Object>
是不同的類型,但是卻是相同的類。盡管 Integer
擴(kuò)展 Object
,但是 List<Integer>
不是 List<Object>
,并且不能賦給 List<Object>
或者強(qiáng)制轉(zhuǎn)換成 List<Object>
。
另一方面,現(xiàn)在有了一個新的古怪的類型叫做 List<?>
,它是 List<Integer>
和 List<Object>
的父類。并且有一個更加古怪的 List<? extends Number>
。類型層次的結(jié)構(gòu)和形狀也變得復(fù)雜得多。類型和類不再幾乎是相同的東西了。
extends 的新含意
在 Java 語言引入泛型之前,extends
關(guān)鍵字總是意味著創(chuàng)建一個新的繼承自另一個類或接口的類或接口。
引入泛型之后,extends
關(guān)鍵字有了另一個含意。將 extends
用在類型參數(shù)的定義中(Collection<T extends Number>
)或者通配符類型參數(shù)中(Collection<? extends Number>
)。
當(dāng)使用 extends
來指示類型參數(shù)限制時,不需要子類-父類關(guān)系,只需要子類型-父類型關(guān)系。還要記住,有限制類型不需要是該限制的嚴(yán)格子類型;也可以是 該限制。換句話說,對于 Collection<? extends Number>
,您可以賦給它 Collection<Number>
(盡管 Number
不是 Number
的嚴(yán)格子類型)和 Collection<Integer>
、Collection<Long>
、Collection<Float>
等等。
在任何這些含意中,extends
右邊的類型都可以是參數(shù)化類型(Set<V> extends Collection<V>
)。
posted @
2005-08-24 11:36 Dave 閱讀(191) |
評論 (0) |
編輯 收藏
Eclipse 運(yùn)行命令行參數(shù)大全
包括英文版本和中文版本兩種的說明, 特別需要值得一提的是那個 -nl 參數(shù), 可以指定程序啟動時所使用的語言. 例如:
eclipse -nl en_US
將啟動英文語言, 這個特性在安裝了國際化語言包以后特別有用, 可以方便的切換各個語言的版本. 注意 IBM WSAD v5.1 也支持這個功能.
運(yùn)行 Eclipse
將 Eclipse 驅(qū)動程序安裝(解壓縮)到某個目錄(例如,c:\eclipse)中之后,通過運(yùn)行頂級安裝目錄中的 Eclipse 可執(zhí)行文件來啟動"工作臺"。在 Windows 系統(tǒng)上,該可執(zhí)行文件稱為 eclipse.exe,而在 Linux 系統(tǒng)上稱為 eclipse。注意:下列討論描述 Windows 系統(tǒng)上的設(shè)置。Linux 上的設(shè)置是相似的。
如果您沒有另行指定,則平臺將缺省工作區(qū)目錄創(chuàng)建為可執(zhí)行文件的兄弟目錄(例如 c:\eclipse\workspace)。此工作區(qū)目錄用作項目的缺省內(nèi)容區(qū),還用于保存任何必需的元數(shù)據(jù)。要進(jìn)行共享安裝或多工作區(qū)安裝,應(yīng)明確指出工作區(qū)的位置而不是使用缺省值。有兩種控制工作區(qū)位置的方法:使用當(dāng)前工作目錄或使用 -data 命令行自變量。
將工作區(qū)位置設(shè)置為在當(dāng)前工作目錄內(nèi)
在此方案中,工作區(qū)位置將是當(dāng)前工作目錄中稱為 workspace 的目錄。
實現(xiàn)此目的最容易的方法可能是使用下列步驟來創(chuàng)建快捷方式:
導(dǎo)航到 Windows 資源管理器中的 eclipse.exe 并使用右鍵拖動來創(chuàng)建 eclipse.exe 的快捷方式。
編輯快捷方式的屬性,以使啟動位置:字段標(biāo)識工作區(qū)位置的父目錄(例如,c:\users\robert)。
關(guān)閉屬性對話框并雙擊快捷方式(如果提供的目錄為 c:\users\robert,則工作區(qū)位置將為 c:\users\robert\workspace)。
當(dāng)然,您也可以使用命令提示符(通過將目錄切換為工作區(qū)父目錄然后運(yùn)行 eclipse.exe)來獲得同樣的效果。
使用 -data 設(shè)置工作區(qū)的特定位置
要使用 -data 命令行自變量,只要將 -data your_workspace_location(例如,-data c:\users\robert\myworkspace)添加至快捷方式屬性中的目標(biāo)字段或顯式地將它包括在命令行上。
使用 -vm 設(shè)置 java VM
建議顯式指定在運(yùn)行 Eclipse 時要使用哪個 Java VM。使用 -vm 命令行自變量(例如,-vm c:\jre\bin\javaw.exe)可以實現(xiàn)此目的。如果不使用 -vm,則 Eclipse 將使用在 O/S 路徑上找到的一個 Java VM。當(dāng)安裝其它產(chǎn)品時,它們可更改您的路徑,導(dǎo)致在下一次啟動 Eclipse 時使用另一 Java VM。
運(yùn)行 Eclipse 中的高級主題
Eclipse 可執(zhí)行文件及平臺本身提供了人們感興趣的開發(fā)或調(diào)試 Eclipse 各部件的許多執(zhí)行選項。運(yùn)行 Eclipse 可執(zhí)行文件的一般格式是:
eclipse [platform options] [-vmargs [Java VM arguments]]
Eclipse 啟動參數(shù) 命令 描述 原因
-arch architecture
定義 Eclipse 平臺在其上運(yùn)行的處理器體系結(jié)構(gòu)。Eclipse 平臺通常使用 Java os.arch 屬性的常用值來計算最佳設(shè)置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getOSArch() 用于插件。示例值有:"x86"、"sparc"、"PA-RISC"和"ppc"。 2.0
-application applicationId
要運(yùn)行的應(yīng)用程序。應(yīng)用程序由向 org.eclipse.core.runtime.applications 擴(kuò)展點(diǎn)提供擴(kuò)展的插件來聲明。通常不需要此自變量。如果指定了此項,則該值會覆蓋配置提供的值。如果不指定此項,則會運(yùn)行"Eclipse 工作臺"。 1.0
-boot bootJarURL
(建議不使用;用 -configuration 代替;支持 1.0 兼容)。Eclipse 平臺的引導(dǎo)插件代碼(boot.jar)的位置,表示為 URL。如果指定此項,則會用它來為裝入 Eclipse 平臺引導(dǎo)程序類裝入器的類裝入器設(shè)置類路徑。僅當(dāng)更改 startup.jar 和 boot.jar 的相對位置時才需要它。注意,不允許使用相對 URL。 *1.0
-classloaderproperties [file]
如果指定的話,則使用給定位置處的類裝入器屬性文件來激活平臺類類裝入器增強(qiáng)。文件自變量可以是文件路徑或 URL。注意,不允許使用相對 URL。單擊此處以獲得更多詳細(xì)信息。 2.0.2
-configuration configurationFileURL
Eclipse 平臺配置文件的位置,表示為 URL。配置文件確定 Eclipse 平臺、可用插件集和主要功能部件的位置。注意,不允許使用相對 URL。當(dāng)安裝或更新 Eclipse 平臺時配置文件被寫至此位置。 2.0
-consolelog
將 Eclipse 平臺的錯誤日志鏡像到用來運(yùn)行 Eclipse 的控制臺。與 -debug 組合時很方便使用。 1.0
-data workspacePath
要運(yùn)行 Eclipse 平臺的工作區(qū)的路徑。工作區(qū)位置也是項目的缺省位置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-debug [optionsFile]
將平臺置于調(diào)試方式,并從給定位置處的文件裝入調(diào)試選項(如果指定的話)。此文件指示哪些調(diào)試點(diǎn)可用于插件以及是否已啟用它們。如果未給出文件位置,則平臺在啟動 eclipse 的目錄中查找稱為".options"的文件。URL 和文件系統(tǒng)路徑都可作為文件位置。 1.0
-dev [classpathEntries]
將平臺置于開發(fā)方式。將可選類路徑條目(用逗號分隔的列表)添加至每個插件的運(yùn)行時類路徑。例如,當(dāng)工作區(qū)包含要開發(fā)的插件時,指定 -dev bin 會為每個插件項目的名為 bin 的目錄添加類路徑條目,允許在其中存儲最新生成的類文件。除去了冗余或不存在的類路徑條目。 1.0
-endsplash params
用于在 Eclipse 平臺啟動并運(yùn)行時關(guān)閉閃屏的內(nèi)部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0
-feature featureId
主要功能部件的標(biāo)識。主要功能部件為 Eclipse 的已啟動實例提供了產(chǎn)品個性,并確定使用的產(chǎn)品定制信息。 2.0
-keyring keyringFilePath
磁盤上授權(quán)數(shù)據(jù)庫(或"密鑰環(huán)"文件)的位置。此自變量必須與 -password 選項配合使用。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-nl locale
定義 Eclipse 平臺在其上運(yùn)行的語言環(huán)境的名稱。Eclipse 平臺通常自動計算最佳設(shè)置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getNL() 用于插件。示例值有:"en_US"和"fr_FR_EURO"。 2.0
-nolazyregistrycacheloading
取消激活裝入優(yōu)化的平臺插件注冊表高速緩存。缺省情況下,僅當(dāng)需要時才從注冊表高速緩存(可用時)中裝入擴(kuò)展的配置元素,以減少內(nèi)存占用。此選項將在啟動時強(qiáng)制完全裝入注冊表高速緩存。 2.1
-noregistrycache
繞過讀寫內(nèi)部插件注冊表高速緩存文件。 2.0
-nosplash
運(yùn)行平臺而不顯示閃屏。 1.0
-os operatingSystem
定義 Eclipse 平臺在其上運(yùn)行的操作系統(tǒng)。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設(shè)置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getOS() 用于插件,并用于解析插件清單文件中提及的路徑中 $os$ 變量的出現(xiàn)。示例值有:"win32"、"linux"、"hpux"、"solaris"和"aix"。 1.0
-password password
授權(quán)數(shù)據(jù)庫的密碼。與 -keyring 選項配合使用。 1.0
-perspective perspectiveId
啟動時要在活動工作臺窗口中打開的透視圖。如果沒有指定該參數(shù),則將打開關(guān)閉時活動的透視圖。 1.0
-plugincustomization propertiesFile
包含插件首選項缺省設(shè)置的屬性文件的位置。這些缺省設(shè)置覆蓋在主要功能部件中指定的缺省設(shè)置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 2.0
-plugins pluginsFileURL
(建議不使用;用 -configuration 代替;支持 1.0 兼容)。 指定 Eclipse 平臺查找插件的文件的位置,表示為 URL。該文件為屬性文件格式,其中鍵是任意用戶定義名稱,值是指向 plugin.xml 文件的顯式路徑或指向包含插件的目錄的路徑的用逗號分隔的列表。注意,不允許使用相對 URL。如果指定此項,則此選項會導(dǎo)致創(chuàng)建適當(dāng)?shù)呐R時配置。 *1.0
-refresh
啟動時執(zhí)行工作區(qū)的全局刷新的選項。這將使從上次平臺運(yùn)行以來在文件系統(tǒng)中所做的任何更改一致。 1.0
-showlocation
用于在窗口標(biāo)題欄中顯示工作區(qū)的位置的選項。在發(fā)行版 2.0 中,此選項僅與 -data 命令行自變量一起使用。 2.0
-showsplash params
用于顯示閃屏(由可執(zhí)行的 Eclipse 平臺啟動器執(zhí)行)的內(nèi)部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0
-vm vmPath
要用來運(yùn)行 Eclipse 平臺的"Java 運(yùn)行時環(huán)境"(JRE)的位置。如果不指定此項,則 JRE 位于 jre(它是 Eclipse 可執(zhí)行文件的兄弟目錄)。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-ws windowSystem
定義 Eclipse 平臺在其上運(yùn)行的 Windows 系統(tǒng)。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設(shè)置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getWS() 用于插件、用于配置 SWT 以及用于解析插件清單文件中提及的路徑中 $ws$ 變量的出現(xiàn)。示例值有:"win32"、"motif"和"gtk"。 1.0
將 -vmargs 條目后面的所有自變量(但不包括 -vmargs)作為虛擬機(jī)自變量(即,在要運(yùn)行的類的前面)直接傳遞到所指示的 Java VM。注意:如果 Eclipse 啟動在 Java vm 自變量(-vmargs)之后提供的自變量(例如,-data),則 Eclipse 將不會啟動并且您將接收到"JVM 已終止。出口代碼為 1"的錯誤。
在不同的 VM 上運(yùn)行
在 J9 上運(yùn)行 Eclipse
當(dāng)在 J9 版本 1.5 上運(yùn)行 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
當(dāng)在 J9 版本 2.0 上運(yùn)行 Eclipse 時,J9W 選擇的缺省自變量應(yīng)為合適的選項。但是,要覆蓋 Eclipse 可執(zhí)行文件以內(nèi)部方式自動設(shè)置的參數(shù),必須指定 -vmargs 不帶任何參數(shù),如下所示:
eclipse.exe [eclipse arguments] -vm path_to_j9w.exe -vmargs
有關(guān)進(jìn)一步信息,參考 J9 VM 文檔和幫助。
在 IBM Developer Kit, Java(TM) Technology Edition VM 上運(yùn)行 Eclipse
IBM Developer Kit, Java(TM) Technology Edition 1.3 Linux 的缺省 VM 設(shè)置適合進(jìn)行初期研究工作,但在進(jìn)行大型開發(fā)時是不夠的。對于大型開發(fā),應(yīng)修改 VM 自變量以使有更多的堆可用。例如,下列設(shè)置將允許 Java 堆增大為 256MB:
posted @
2005-08-22 10:49 Dave 閱讀(215) |
評論 (0) |
編輯 收藏
愛因斯坦曾經(jīng)說:“任何事情都應(yīng)該越簡單越好,而不是比較簡單。”實際上,科學(xué)真理的目的就是在假設(shè)的前提下去簡化一個理論,這樣,人們可以去關(guān)注真正重要的問題。在企業(yè)軟件開發(fā)中,道理是一樣的。
簡化企業(yè)軟件開發(fā)的一個關(guān)鍵是,提供一個這樣的應(yīng)用框架:它可以使開發(fā)人員不用關(guān)注于很多復(fù)雜的問題,比如事務(wù)處理、安全和持久化等。一個設(shè)計良好的框架將提升代碼的可復(fù)用性,提高開發(fā)者的效率,并得到更高質(zhì)量的軟件。然而,目前J2EE 1.4下的EJB 2.1 框架被廣泛認(rèn)為是設(shè)計較差而且過度復(fù)雜的。不滿足于EJB2.1框架,JAVA開發(fā)者使用了很多其他的中間件服務(wù)產(chǎn)品。最值得關(guān)注的是,以下兩個框架吸引了大量開發(fā)者的興趣和積極反饋。這兩個框架很可能成為未來企業(yè)JAVA應(yīng)用開發(fā)框架的選擇。
Spring框架是一個廣受歡迎的但是非標(biāo)準(zhǔn)的開源框架。它主要由Interface21公司開發(fā)和控制。Spring框架的體系結(jié)構(gòu)是基于注射依賴(DI)模式。Spring框架使用了大量的XML配置文件,它可以獨(dú)立應(yīng)用,或者在現(xiàn)有的應(yīng)用服務(wù)器上工作。
EJB 3.0框架是JCP定義的并且被所有主流J2EE提供商支持的標(biāo)準(zhǔn)框架。EJB 3.0規(guī)范的預(yù)發(fā)布版本目前已經(jīng)有開源的和商業(yè)的實現(xiàn),如JBOSS和ORACLE。EJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能。譯者注)
這兩個框架有著一個共同的核心設(shè)計理念:它們的目標(biāo)是為松耦合的POJO類提供中間件服務(wù)??蚣芡ㄟ^在運(yùn)行時截取執(zhí)行環(huán)境,或?qū)⒎?wù)對象注射給POJO類的方式,將應(yīng)用服務(wù)和POJO類“連接”起來。POJO類本身并不關(guān)注如何“連接”,而且也很少依賴于框架。這樣,開發(fā)者可以將注意力集中在業(yè)務(wù)邏輯上,可以對他們的POJO類進(jìn)行與框架無關(guān)的單元測試。并且,由于POJO類不需要繼承框架的類或?qū)崿F(xiàn)框架提供的接口,開發(fā)者可以在更加靈活性的基礎(chǔ)上構(gòu)建繼承體系,和搭建應(yīng)用。
盡管有著共同的理念,但這兩個框架采取了不同的方式來提供POJO服務(wù)。由于已經(jīng)出版了大量的比較Spring與EJB2.1或者EJB3.0與EJB2.1的書籍和文章,而沒有關(guān)于比較Spring和EJB3.0的認(rèn)真研究,因此,本文將考察它們之間幾個關(guān)鍵的不同,討論他們優(yōu)缺點(diǎn)。本文談到的主題同樣適用于其他不太有名的但同樣提供“松耦合POJO” 設(shè)計的企業(yè)中間件框架。我希望,這篇文章可以幫助你選者最合適的你需求的框架。
提供商無關(guān)性
開發(fā)者選擇JAVA平臺的一個最重要的原因就是它的提供廠商無關(guān)性。EJB 3.0是一個被設(shè)計為對提供商沒有依賴性的開放的標(biāo)準(zhǔn)。EJB 3.0規(guī)范由企業(yè)JAVA社區(qū)的主流開源組織和廠商共同編寫和支持的。EJB 3.0框架使開發(fā)者的應(yīng)用程序?qū)崿F(xiàn)可以獨(dú)立于應(yīng)用服務(wù)器。比如,JBoss的EJB 3.0的實現(xiàn)是基于Hibernate的,Oracle的EJB 3.0實現(xiàn)是基于TopLink的,但是,在JBoss或者Oracle上跑應(yīng)用程序,開發(fā)者既不需要去學(xué)習(xí)Hibernate,也不需要學(xué)習(xí)TopLink提供的獨(dú)特API。廠商無關(guān)性使EJB 3.0框架區(qū)別于當(dāng)前其他任何的POJO中間件框架。
然而,就象很多EJB 3.0的批評者很快指出的一樣,目前EJB 3.0規(guī)范正在編寫還未完全完成最終發(fā)布版。很有可能,還需要1至2年,EJB 3.0才會被主流J2EE廠商完全接受。但是,就算你的應(yīng)用服務(wù)器本身不支持EJB 3.0,你也可以通過下載和安裝一個“可嵌入的” EJB 3.0產(chǎn)品,來使你的應(yīng)用服務(wù)器支持EJB 3.0應(yīng)用。比如,JBoss“可嵌入的” EJB 3.0產(chǎn)品是開源的,它可以運(yùn)行在任何兼容J2SE-5.0環(huán)境下(如你的應(yīng)用服務(wù)器),目前處于Beta版測試中。其他廠商同樣可以快速發(fā)布他們自己的可嵌入EJB 3.0產(chǎn)品,特別是規(guī)范中“數(shù)據(jù)持久化”部分。
另一方面,Spring一直是一個非標(biāo)準(zhǔn)的技術(shù),而且在可以預(yù)計的未來仍將如此。盡管你在任何應(yīng)用服務(wù)器都上可以使用Spring框架,但基于Spring的應(yīng)用仍然被限制于Spring本身和在你的應(yīng)用中使用到的Spring提供的各種特別服務(wù)。
由于Spring框架是一個開源項目,因此,它使用的配置文件XML格式和開發(fā)接口都是私有的。當(dāng)然,這種限制不僅體現(xiàn)在Spring框架中,其他任何非標(biāo)準(zhǔn)產(chǎn)品都會有這種限制。但是,你的Spring應(yīng)用的長期生存能力將依賴于Spring項目本身(或者說Interface 21公司,因為它雇傭了大多數(shù)的Spring核心開發(fā)人員)。并且,如果你使用了Spring提供的特殊服務(wù),如Spring事務(wù)管理器或者Spring MVC,你同樣被限制于Spring提供的API。
并且,Spring應(yīng)用是知道后端服務(wù)提供者的(即應(yīng)用程序是知道服務(wù)提供者的,這樣應(yīng)用程序?qū)谝欢ǔ潭壬弦蕾囉诜?wù)提供方:譯者注)。例如,對于數(shù)據(jù)持久化服務(wù),Spring框架提供了不同的DAO和模板Helper類,用于JDBC、Hibernate,、iBatis和JDO。這樣,假如你需要改變一個Spring應(yīng)用的持久化服務(wù)提供者(如,從JDBC換到Hibernate),你將需要重構(gòu)你的系統(tǒng)應(yīng)用代碼,來使用新的Helper類。
服務(wù)整合 Spring框架是建立在應(yīng)用服務(wù)器和服務(wù)庫之上,它的服務(wù)整合代碼(如數(shù)據(jù)訪問模板和Helper類)是基于框架的,并暴露給應(yīng)用開發(fā)者。相反,EJB 3.0框架是緊密整合到應(yīng)用服務(wù)器中的,它的服務(wù)整合代碼是封裝在一個標(biāo)準(zhǔn)的接口下的。
因此,EJB 3.0廠商可以輕松的優(yōu)化整體性能和開發(fā)者體驗。如,在JBoss的EJB 3.0實現(xiàn)中,當(dāng)你通過實體管理器持久化一個實體BEAN POJO時,Hibernate session事務(wù)將在JTA事務(wù)提交時自動提交。通過使用簡單的@PersistenceContext注解(例子參看后面文章),你可以甚至可以將實體管理器和其下的Hibernate事務(wù)綁定到一個有狀態(tài)的session bean上。應(yīng)用程序事務(wù)可以在一個session中跨越多個線程,在事務(wù)性的WEB應(yīng)用中這是非常有用的,如多頁面的購物車。
基于EJB 3.0 框架、Hibernate、和JBoss 內(nèi)部Tomcat的緊密整合,上面提到的簡單的整合的編程接口是可能的。Oracle的EJB 3.0框架和它內(nèi)部的Toplink持久服務(wù)可以達(dá)到同樣層次的整合。
EJB 3.0中整合服務(wù)的另一個好例子是集群支持。假如你部署一個EJB 3.0應(yīng)用到一個集群服務(wù)器,所有的故障切換、負(fù)載均衡、分布式緩存、和狀態(tài)復(fù)制服務(wù)對于應(yīng)用程序來說,都是自動完成的。集群服務(wù)被隱藏在EJB 3.0編程接口之下,對于EJB 3.0開發(fā)者來說,這些服務(wù)都是完全透明的。
在Spring中,優(yōu)化框架和服務(wù)之間交互更加困難一些。例如,想要用Spring的聲明式事務(wù)服務(wù)來管理Hibernate事務(wù),必須在XML配置文件中明確的配置Spring的事務(wù)管理器(TransactionManager)和Hibernate SessionFactory對象。Spring應(yīng)用開發(fā)者必須自己管理跨越多個HTTP請求的事務(wù)。并且,沒有簡單的方法可以在Spring應(yīng)用中實現(xiàn)集群服務(wù)
服務(wù)聚合的靈活性 由于Spring中的服務(wù)整合代碼是作為編程接口暴露給應(yīng)用開發(fā)者的,因此開發(fā)人員可以根據(jù)需要來聚合多個服務(wù)。這個特性使你可以集成一個你自己的“輕量”級應(yīng)用服務(wù)器。Spring的一個通常的用法是將Tomcat和Hibernate連接起來來支持簡單的數(shù)據(jù)庫驅(qū)動的WEB應(yīng)用程序。在這種情況下,Spring本身提供了事務(wù)管理服務(wù),Hibernate提供了持久化服務(wù),這種設(shè)置本身就創(chuàng)建了一個小型的應(yīng)用服務(wù)器。
通常,EJB 3.0應(yīng)用服務(wù)器不提供給開發(fā)者這種按照你的需要來選擇服務(wù)的靈活性。大多數(shù)情況,你會得到一系列已經(jīng)預(yù)先打包好的特性,其中有些你可能是不需要的。然而,如果應(yīng)用服務(wù)器提供了模塊內(nèi)部的獨(dú)特設(shè)計,就象JBOSS一樣,你可以不去關(guān)心這些不必要的特性。在任何情況下,去定制一個全功能的應(yīng)用服務(wù)器并不是一個瑣碎而沒有意義的工作。
當(dāng)然,如果一個應(yīng)用不是一個單一的結(jié)點(diǎn),你將需要連接多個應(yīng)用服務(wù)器提供的服務(wù)(如資源池、消息隊列和集群)。這種情況下,從總的資源消耗上看,Spring框架就和任何EJB 3.0方案一樣是“重量級”的。
為了進(jìn)行容器外的單元測試,Spring的靈活的服務(wù)聚合也可以來連接假對象,來替代真的服務(wù)對象。在EJB 3.0應(yīng)用中,大多數(shù)的組件都是簡單POJO,他們可以容易進(jìn)行容器外的單元測試。但是,如果要測試與容器服務(wù)相關(guān)的服務(wù)對象(如持久化實體管理器),更好的方式是進(jìn)行容器內(nèi)的測試,因為這樣比使用假對象來替代的方式更加容易,更加健壯,而且更加準(zhǔn)確。
XML vs. 注解
從應(yīng)用開發(fā)者的角度來看,Spring的編程接口主要基于XML配置文件,而EJB 3.0則大量的使用了JAVA注解。XML文件可以表達(dá)復(fù)雜的關(guān)系,但是它們更加冗長而且不健壯。注解的方式很簡單明了,但是很難去表達(dá)復(fù)雜的或者繼承性的結(jié)構(gòu)。
Spring和EJB 3.0分別選擇了XML和注解方式,這取決于框架的體系結(jié)構(gòu):由于注釋只能描述相當(dāng)少的配置信息,只有一個預(yù)先整合好的框架(如大多數(shù)重要事情已經(jīng)在框架中實現(xiàn)了)才能大量的使用注釋作為它的配置選項。象我們討論的一樣,EJB 3.0滿足了這些要求,而Spring作為一個一般的注射依賴框架,它沒有做到這一點(diǎn)。
當(dāng)然,由于EJB 3.0和Spring相互學(xué)習(xí)了很多特性,所以,它們都在某種層次上支持XML和注釋。例如,EJB 3.0中可以應(yīng)用XML配置文件來作為一個選擇性的機(jī)制,用來改變注釋的默認(rèn)行為。注釋也可以用來配置一些Spring服務(wù)。
研究XML和注釋直接區(qū)別的最好的方式就是通過例子。在下面的幾節(jié)中,我們將一起看一下EJB 3.0和Spring是如何為應(yīng)用程序提供關(guān)鍵服務(wù)的。
聲明式服務(wù) EJB 3.0和Spring都將運(yùn)行時服務(wù)(如事務(wù)管理、安全、日志、消息、和信息服務(wù))連接給應(yīng)用程序。由于這些服務(wù)同應(yīng)用程序的業(yè)務(wù)邏輯并不是直接相關(guān)的,因此,它們不被應(yīng)用程序本身來管理。相反,這些服務(wù)被服務(wù)容器(如EJB 3.0和Spring)以不可見的方式在運(yùn)行時提供給應(yīng)用程序。開發(fā)人員(或系統(tǒng)管理員)通過配置來告訴容器什么時候,以怎樣的方式來應(yīng)用這些服務(wù)。
EJB 3.0通過JAVA注解的方式來配置聲明式服務(wù),Spring則通過XML配置文件來完成。大多數(shù)情況下,EJB 3.0 的注解方式是應(yīng)用這種服務(wù)的更加簡單和優(yōu)美的方式。下面是一個在EJB 3.0中對一個POJO的方法使用事務(wù)管理服務(wù)的例子。
public class Foo {
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
你可以對一段代碼聲明多個屬性,并應(yīng)用多個服務(wù)。下面是一個對EJB 3.0中POJO類同時使用事務(wù)管理服務(wù)和安全服務(wù)的例子。
@SecurityDomain("other")
public class Foo {
@RolesAllowed({"managers"})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
使用XML指定代碼屬性和配置聲明服務(wù)將導(dǎo)致冗長的和不桅頂?shù)呐渲梦募?。下面是Spring應(yīng)用中一個XML元素的例子,它用來在Foo.bar()方法上應(yīng)用一個非常簡單的Hibernate事務(wù)。
<!-- 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文件的復(fù)雜程度將隨著你對同一個POJO類增加的攔截器的數(shù)量程幾何增長。意識到了僅使用XML配置文件的限制性,Spring支持在JAVA源代碼中使用Apache Commons metadata來指定事物屬性。在最新的Spring 1.2中,JDK-1.5風(fēng)格的注釋也被支持。為了使用事務(wù)元數(shù)據(jù),你需要為上面例子中的AttributesTransactionAttributeSource 改變一個transactionAttributeSource bean,并且增加一個附加的對元數(shù)據(jù)攔截器的設(shè)置。
<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"/>
當(dāng)你有許多事務(wù)方法時,Spring元數(shù)據(jù)簡化了transactionAttributeSource元素。但是它沒有解決XML配置文件的根本問題:仍然需要冗長的、易錯的事務(wù)攔截器,事務(wù)管理器,和事務(wù)屬性。
注射依賴
中間件容器的一個主要優(yōu)點(diǎn)是它們使得程序開發(fā)人員可以去構(gòu)建松耦合的應(yīng)用程序。服務(wù)使用者僅僅需要知道服務(wù)接口就可以使用服務(wù)。容器把具體的服務(wù)實現(xiàn)實例化,然后將它們提供給服務(wù)使用者。這樣,容器可以在可替換的服務(wù)實現(xiàn)之間進(jìn)行切換,而不改變服務(wù)接口和服務(wù)使用者代碼。
注射依賴模式是實現(xiàn)松耦合應(yīng)用程序的一個最好的方式。比起以前的方式,如通過JNDI進(jìn)行查找或回調(diào)容器,注射依賴模式更容易使用,而且更加優(yōu)美。使用注射依賴模式,框架扮演了構(gòu)建服務(wù)的對象工廠角色,然后根據(jù)運(yùn)行時的配置,把這些服務(wù)對象注射到應(yīng)用程序的POJO類中。從程序開發(fā)人員的角度看,作為客戶端使用者的POJO在需要使用服務(wù)對象前就自動的得到了它們。
Spring 和 EJB 3.0都提供了大量的DI模式支持。但是,它們之間也有著根本的不同。Spring支持了通常意義上的但是復(fù)雜的基于XML配置文件的注射依賴API;EJB 3.0支持的注射大多數(shù)通用服務(wù)對象(如,EJB和容器對象)和JNDI對象,它通過簡單的JAVA注解來完成。
EJB 3.0的注射注解相當(dāng)?shù)暮啙嵰子谩?#64;Resource標(biāo)簽注射大多數(shù)的通過服務(wù)對象和JNDI對象。下面的例子顯示了如何將JNDI提供的服務(wù)器缺剩數(shù)據(jù)源對象注射給一個POJO的一個字段。DefaultDS是這個數(shù)據(jù)源的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方法注射給使用者。應(yīng)用程序不用顯示的調(diào)用setter方法,在任何其他方法被調(diào)用前容器將調(diào)用setter方法完成注射。
@Resource
public void setSessionContext (SessionContext ctx) {
sessionCtx = ctx;
}
對于更復(fù)雜的服務(wù)對象,還有一些特殊的注射注解。例如,@EJB 注解被用來注射EJB stubs,@PersistenceContext注解被用來注射實體管理器對象,這些對象負(fù)責(zé)處理EJB 3.0實體Bean的數(shù)據(jù)訪問操作。 下面的例子給出如何將一個實體管理器注射到一個有狀態(tài)Session Bean中。@PersistenceContext注解的類型屬性描述了被注射的的實體管理器有一個擴(kuò)展的事務(wù)容器:它不會隨著JTA事務(wù)管理器自動提交事務(wù),因此它可以應(yīng)用在當(dāng)session中有多次操作的應(yīng)用事務(wù)管理時。
@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 規(guī)范定義了可以通過注解來被注射使用的服務(wù)器資源。但是,它不支持用戶自定義的POJO類之間的相互注射。
在Spring中,為了將服務(wù)對象注射到你的POJO類中,你首先需要定義一個setter方法(或有參數(shù)的構(gòu)造函數(shù)) 。下面的例子演示了 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);
}
}
因此,你可以指定容器如何得到這個服務(wù),并且在運(yùn)行時通過配置文件中XML元素的連接關(guān)系把它提供給POJO。下面的例子顯示了連接一個數(shù)據(jù)源到一個Hibernate session 工廠、session 工廠到Hibernate模板對象、模板對象最后到應(yīng)用程序POJO類,整個過程的XML配置。
Spring 代碼復(fù)雜性的部分原因是,我們需要手工的去注射Hibernate相關(guān)類,然而,EJB 3.0 實體管理器被服務(wù)器自動管理和配置。但是,這使我們返回到了這樣的討論:Spring 不象EJB 3.0 一樣,它不同服務(wù)緊密整合在一起。
<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的注射依賴比較復(fù)雜,但是它非常強(qiáng)大。你可以注射任何POJO到另外的POJO中,包括程序中自定義的。
如果你確實想在EJB 3.0應(yīng)用中使用Spring的注射依賴功能,你可以將一個Spring Bean工廠類通過JNDI注射到一個EJB中。在某些EJB 3.0 應(yīng)用服務(wù)器中,廠商可能會定義一些非標(biāo)準(zhǔn)的API用來注射任意的POJO類。一個很好的例子是JBoss MicroContainer,它處理了AOP依賴性,因此它是甚至比Spring 更加通用。
結(jié)論
盡管Spring 和EJB 3.0的目標(biāo)都是提供企業(yè)服務(wù),使得POJO可以松耦合,但是它們實現(xiàn)的方式非常不同。在兩個框架中注射依賴模式都有大量的應(yīng)用。
通過EJB 3.0的標(biāo)準(zhǔn)方式、大量應(yīng)用的注解、還有同應(yīng)用服務(wù)器緊密整合性,這些提供了更高的廠商無關(guān)性和開發(fā)人員工作效率。Spring的以XML為中心的配置文件和注射依賴的連貫使用,允許開發(fā)人員去構(gòu)造更加靈活的應(yīng)用系統(tǒng),并且可以同時與多個應(yīng)用服務(wù)提供者同時工作。
感謝
作者感謝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服務(wù)。
?? cache-invalidation-service.xml:允許借助于JMS,而實現(xiàn)對EJB緩存的控制。
?? client-deployer-service.xml:部署J2EE應(yīng)用客戶。
?? ear-deployer.xml:部署J2EE EAR應(yīng)用。
?? ejb-deployer.xml:部署J2EE EJB應(yīng)用。
?? hsqldb-ds.xml:設(shè)置嵌入式Hypersonic數(shù)據(jù)庫服務(wù),并將其作為默認(rèn)數(shù)據(jù)源。
?? http-invoker.sar:通過RMI/HTTP方式訪問到MBean和EJB。
?? jboss-aop.deployer:提供AspectManagerService,并部署JBoss AOP應(yīng)用。
?? jboss-hibernate.deployer:部署Hibernate存檔(HAR文件)。
?? jboss-local-jdbc.rar和jboss-xa-jdbc.rar:集成JDBC驅(qū)動的JCA資源適配器,它們分別支持DataSource和XADataSource。但是,這并沒有提供專有JCA實現(xiàn)。
?? jboss-ws4ee.sar:提供J2EE Web服務(wù)支持。
?? jbossjca-service.xml:JBoss JCA實現(xiàn),使得在JBoss中部署JCA資源適配器成為可能。
?? jbossweb-tomcat50-sar:含有嵌入式Tomcat服務(wù)的展開SAR文件。它為JBoss提供了標(biāo)準(zhǔn)的Web容器。
?? jms:將JMS相關(guān)的服務(wù)聚集在一起,并放置在jms目錄中。
?? hsqldb-jdbc-state-service.xml:使用HSQLDB管理狀態(tài)。
?? hsqldb-jdbc2-service.xml:使用嵌入式HSQL數(shù)據(jù)庫實現(xiàn)緩存和持久化。它還包含了JMS實現(xiàn)的核心服務(wù),即DestinationManager MBean。
?? jbossmq-destinations-service.xml:供JBoss測試套件使用的JMS Topic和Queue。
?? jbossmq-service.xml:JMS其他服務(wù),包括攔截器配置。
?? jms-ds.xml:將JBoss消息實現(xiàn)作為默認(rèn)JMS提供商。并且,它還提供JCA配置信息,以供集成JBoss JCA和JMS資源適配器使用。
?? jms-ra.rar:資源適配器,供JCA處理JMS連接工廠使用。
?? jbossmq-httpil.sar:提供JMS調(diào)用層,從而實現(xiàn)HTTP方式使用JMS。
?? jvm-il-service.xml:配置本地JMS傳輸調(diào)用層,供本地JVM使用JMS。
?? uil2-service.xml:配置JMS版本2統(tǒng)一調(diào)用層。這是一種可靠的、自定義的、基于Socket的傳輸方式。推薦在不同JVM間使用它。
?? jmx-console.war:JMX控制臺應(yīng)用。前面討論過。
?? jmx-invoker-server.xml:為遠(yuǎn)程訪問JMX MBean服務(wù)器提供支持。
?? mail-ra.rar:為JavaMail提供資源適配器。
?? mail-service.xml:允許應(yīng)用和服務(wù)在JBoss中使用JavaMail。請注意,郵件服務(wù)器相關(guān)信息必須由用戶提供。
?? management:含有可更換管理服務(wù)的子目錄。其中,包含有改進(jìn)的Web控制臺。
?? monitoring-service.xml:配置警告監(jiān)聽器,比如控制臺監(jiān)聽器、E_mail監(jiān)聽器,等等。
?? properties-service.xml:設(shè)置JVM的全局系統(tǒng)屬性(由System.getProperties返回)。
?? schedule-manager-service.xml和scheduler-service.xml:定時任務(wù)服務(wù)。
?? sqlexception-service.xml:為JDBC驅(qū)動提供標(biāo)識一般性SQL異常。
?? uuid-key-generator.sar:生成唯一的、基于UUID的鍵。
all配置提供了其他配置沒有提供的其他服務(wù),用戶可以將這些服務(wù)集成到各自的服務(wù)器配置中。具體如下:
?? cluster-service.xml:群集服務(wù),包括JGroups集成服務(wù)、HA-JNDI、有狀態(tài)會話Bean復(fù)制、CMP2緩存有效性服務(wù)。
?? deploy-hasingleton-service.xml:HASingletonDeployer MBean。用于確保群集中只有單個節(jié)點(diǎn)在deploy-hasingleton目錄部署了服務(wù)。
?? deploy.last/farm-service.xml:farm群集部署服務(wù)。用于確保它在所有其他服務(wù)部署之后才部署其本身。
?? ebxmlrr-service.xml:JAXR注冊服務(wù)實現(xiàn)。
?? iiop-service.xml:實現(xiàn)對CORBA、IIOP的支持。
?? jbossha-httpsession.sar:遺留的HTTP會話復(fù)制服務(wù)。
?? remoting-service.xml:還處于試驗中的下一代分離式Invoker框架。
?? snmp-adaptor.sar:將JMX通知轉(zhuǎn)換成SNMP陷阱。
?? tc5-cluster-service.xml:用于新的HTTP復(fù)制服務(wù)的TressCache配置。
posted @
2005-08-22 09:25 Dave 閱讀(1208) |
評論 (1) |
編輯 收藏
目錄結(jié)構(gòu):
?? bin:含有啟動、停止以及其他系統(tǒng)相關(guān)腳本。在前面,本書已經(jīng)討論過啟動JBoss應(yīng)用服務(wù)器的run腳本。
?? client:存儲供Java客戶應(yīng)用或者外部Web容器使用的配置文件和JAR文件。用戶可以使用所需要的具體存檔,或者僅僅使用jbossall-client.jar。
?? docs:含有JBoss引用的XML DTD文件(當(dāng)然,還包括JBoss具體配置文件)。同時,還存在JCA(Java Connetor Architecture,Java連接器架構(gòu))實例配置文件,供設(shè)置不同數(shù)據(jù)庫的數(shù)據(jù)源使用(比如MySQL、Oracle、Postgres)。
?? lib:包含運(yùn)行JBoss微內(nèi)核所需的JAR文件。請注意,不要往該目錄添加用戶自身的任何JAR文件。
?? server:包含的各個子目錄都是不同的服務(wù)器配置。通過往run腳本后添加-c <config name>參數(shù)便能夠指定不同的配置。接下來,來看看default服務(wù)器配置。
從根本上考慮,JBoss架構(gòu)是由JMX MBean服務(wù)器、微內(nèi)核、一套可插入式組件服務(wù)以及MBean構(gòu)成的。這種架構(gòu)使得,集成不同的配置變得更加簡單,并且能夠很靈活地滿足用戶的各自需求。用戶不再需要一次性運(yùn)行重量級的應(yīng)用服務(wù)器。同時,用戶可以刪除不再需要使用的組件(這將從很大程度上減少服務(wù)器的啟動時間),并且通過開發(fā)自己的MBean還能夠集成其他服務(wù)到JBoss中。當(dāng)然,如果是運(yùn)行標(biāo)準(zhǔn)J2EE應(yīng)用,則不用理會這些自定義工作。用戶所需要的一切服務(wù),JBoss發(fā)布版都包括了。
server目錄下存在3個服務(wù)器實例配置:all、default以及minimal,它們各自提供了不同的服務(wù)集合。很顯然,如果啟動JBoss服務(wù)器時沒有指定其他配置,則將使用default配置。
minimal:這是啟動JBoss服務(wù)器所要求的最低配置。minimal配置將啟動日志服務(wù)、JNDI服務(wù)器以及URL部署掃描器,以找到新的部署應(yīng)用。對于那些不需要使用任何其他J2EE技術(shù),而只是使用自定義服務(wù)的場合而言,則這種JMX/JBoss配置最適合。它僅僅是服務(wù)器,而不包含Web容器、不提供EJB和JMS支持。
?? default:默認(rèn)配置,它含有大部分J2EE應(yīng)用所需的標(biāo)準(zhǔn)服務(wù)。但是,它不含有JAXR服務(wù)、IIOP服務(wù)、或者其他任何群集服務(wù)。
?? all:提供了所有可用的服務(wù)。它包含RMI/IIOP和群集服務(wù),default配置中沒有提供群集服務(wù)。
用戶也可以添加自身的服務(wù)器配置。最佳做法是,拷貝最接近用戶需求的現(xiàn)有配置,然后修改其具體內(nèi)容。比如,如果用戶不需要使用消息服務(wù),則只需要拷貝default目錄,并重新命名為myconfig,然后刪除jms子目錄。最后,啟動myconfig配置。
run -c myconfig
default服務(wù)器配置目錄的具體內(nèi)容:
conf:含有指定JBoss核心服務(wù)的jboss-service.xml文件。同時,還包括核心服務(wù)的其他配置文件。
?? data:Hypersonic數(shù)據(jù)庫實例將數(shù)據(jù)存儲在此處。JBossMQ(JMS的JBoss實現(xiàn))也使用它存儲消息。
?? deploy:用戶將應(yīng)用代碼(JAR\WAR\EAR文件)部署在此處。同時,deploy目錄也用于熱部署服務(wù)(即,那些能夠從運(yùn)行服務(wù)器動態(tài)添加或刪除的服務(wù))和部署JCA資源適配器。因此,用戶能夠在deploy目錄看到大量的配置文件。尤其是,用戶能夠看到JMX控制臺應(yīng)用(未打包的WAR文件),本書前面討論過。JBoss服務(wù)器將定期掃描該目錄,從而查找是否有組件更新或修改,從而自動完成組件的重新部署。本書后續(xù)章節(jié)將詳細(xì)闡述部署細(xì)節(jié)。
?? lib:服務(wù)器配置所需的JAR文件。用戶可以添加自身的庫文件,比如JDBC驅(qū)動,等等。
?? log:日志信息將存儲到該目錄。JBoss使用Jakarta Log4j包作為其日志功能。同時,用戶可以在應(yīng)用中直接使用Log4j日志記錄功能。
?? tmp:供部署器臨時存儲未打包應(yīng)用使用,也可以作為其他用途。
?? work:供Tomcat編譯JSP使用。
其中,data、log、tmp、work目錄是JBoss創(chuàng)建的。如果用戶沒有啟動過JBoss服務(wù)器,則這些目錄不會被創(chuàng)建。
.
2.2.1 核心服務(wù)
當(dāng)JBoss服務(wù)器啟動時,首先會啟動conf/jboss-service.xml文件指定的核心服務(wù)。
雖然通過conf/jboss-service.xml文件能夠添加其他MBean服務(wù),但是更好的辦法是,將單獨(dú)的配置文件放置在deploy目錄中,因為這將使得用戶的服務(wù)具有熱部署能力。
2.2.2 日志服務(wù)
Log4j是JBoss使用的日志功能包。通過conf/log4j.xml文件能夠控制JBoss的日志功能。
2.2.3 安全性服務(wù)
安全性域信息存儲在login-config.xml文件中,其包含了許多安全性域定義。各個安全性域指定了許多JAAS登陸模塊,供安全性域認(rèn)證使用。當(dāng)用戶需要在應(yīng)用中使用安全性時,需要在JBoss特定部署描述符jboss.xml或jboss-web.xml中指定待使用的安全性域名。
2.2.4 其他服務(wù)
deploy目錄放置的服務(wù)不是核心服務(wù),但具有熱部署能力。用戶可以通過XML描述符文件(*-service.xml)或JBoss服務(wù)存檔(SAR)文件給出服務(wù)。SAR同時含有XML描述符和服務(wù)所要求的其他資源(比如,類、JAR庫文件以及其他存檔),而且SAR是以單個存檔文件給出的。
posted @
2005-08-19 17:47 Dave 閱讀(914) |
評論 (2) |
編輯 收藏
投資是一種追求未來貨幣增值的經(jīng)濟(jì)行為。
新中國的第一張股票:1984年12月發(fā)行的上海飛樂音響公司的股票。
90年12月19日,上證交易所開業(yè)
posted @
2005-08-19 15:36 Dave 閱讀(156) |
評論 (0) |
編輯 收藏
Unlike ad hoc non-EJB architectures, it is similar to EJB architectures in being centered around a layer of managed business service objects. However, this is where the similarity ends. Instead of running inside an EJB container, business objects run inside a lightweight container. A lightweight container isn't tied to J2EE, so it can run in a web container, a stand-alone application, or even an EJB container if necessary. It also isn't tied to the Servlet API, like an MVC web framework, which is a poor choice for managing business objects. Lightweight containers have negligible startup cost and eliminate the deployment step of EJB.
Lightweight containers provide a way to manage and locate business objects. No longer is there any need for JNDI lookups, custom service locators, or Singletons: the lightweight container provides a registry of application objects.
Lightweight containers are both less invasive and more powerful than an EJB container where co-located applications are concerned.
To provide a complete solution, the lightweight container must provide enterprise services such as transaction management. Typically this will invoke AOP interception: transparently weaving in additional behavior, such as transaction management, before and after the execution of business methods.
From the user’s perspective, the web tier is provided by an MVC framework. We can use a dedicated
web framework such as Struts or WebWork, or—in the case of Spring—a web tier that can itself be managed
by the lightweight container and provide close integration with business objects.
Business objects will be POJOs, running inside the lightweight container. They may be “advised” via AOP interception to deliver enterprise services. Unlike EJBs, they don't usually need to depend on container
APIs, meaning that they are also usable outside any container. Business objects should be accessed
exclusively through their interfaces, allowing pluggability of business objects without changing calling
code.
Data access will use a lightweight O/R mapping layer providing transparent persistence, or JDBC via a
simplifying abstraction layer if O/R mapping adds little value.
StrengthsFollowing are some of the advantages of using this architecture:
(1) A simple but powerful architecture.
(2) As with local EJBs or an ad hoc non-EJB solution, horizontal scalability can be achieved by clustering
web containers. The limitations to scalability, as with EJB, will be session state management,
if required, and the underlying database. (However, databases such as Oracle 9i RAC can
deliver huge horizontal scalability independent on the J2EE tier.)
(3) Compared to an ad hoc non-EJB architecture, using a lightweight container reduces rather than
increases complexity. We don't need to write any container-specific code; cumbersome lookup
code is eliminated. Yet lightweight containers are easier to learn and configure than an EJB
container.
(4) Sophisticated declarative services can be provided by a lightweight container with an AOP
capability. For example, Spring's declarative transaction management is more configurable than
EJB CMT.
(5) This architecture doesn't require an EJB container. With the Spring Framework, for example,
you can enjoy enterprise services such as declarative transaction management even in a basic
servlet engine. (Whether you need an application server normally depends on whether you
need distributed transactions, and hence, JTA.)
(6) Highly portable between application servers.
(7) Inversion of Control allows the lightweight container to “wire up” objects, meaning that the complexity
of resource and collaborator lookup is removed from application code, and application
objects don't need to depend on container APIs. Objects express their dependencies on collaborators
through ordinary Java JavaBean properties or constructor arguments, leaving the IoC
container to resolve them at runtime, eliminating any need for tedious-to-implement and hardto-
test lookups in application code.IoC provides excellent ability to manage fine-grained business objects.
(8) Business objects are easy to unit test outside an application server, and some integration testing
may even be possible by running the lightweight container from JUnit tests. This makes it easy
to practice test first development.
WeaknessesFollowing are some of the disadvantages of using this architecture:
(1) Like a local EJB architecture, this architecture can't support remote clients without an additional
remoting facade. However, as with the local EJB architecture, this is easy enough to add, especially
if we use web services remoting (which is becoming more and more important). Only in
the case of RMI/IIOP remoting are remote EJBs preferable.
(2) There's currently no “standard” for lightweight containers comparable to the EJB specification.
However, as application objects are far less dependent on a lightweight container than EJBs are
on the EJB API, this isn't a major problem. Because application objects are plain Java objects,
with no API dependencies, lock-in to a particular framework is unlikely. There are no special
requirements on application code to standardize.
(3) This architecture is currently less familiar to developers than EJB architectures. This is a nontechnical
issue that can hamper its adoption. However, this is changing rapidly.
Implementation IssuesFollowing are some of the implementation issues you might encounter:
(1) Declarative enterprise services can be provided by POJOs using AOP, thus taking one of the best
features of EJB and applying it without most of the complexity of EJB.
(2) A good lightweight container such as Spring can provide the ability to scale down as well as up.
For example, Spring can provide declarative transaction management for a single database
using JDBC connections, without the use of JTA. Yet the same code can run unchanged in a different
Spring configuration taking advantage of JTA if necessary.
(3) A nice variation is ensuring that POJO business objects can be replaced by local EJBs without
changes in calling code. Spring provides this ability: all we need to do is create a local EJB with
a component interface that extends the business interface, if we wish to use EJB. These last two
points make this approach highly flexible, if requirements change. (This results largely from
good OO programming practice and the emphasis on interfaces.)
posted @
2005-08-18 16:19 Dave 閱讀(201) |
評論 (0) |
編輯 收藏
建立信任
及時給予肯定
出錯時調(diào)整注意力
表現(xiàn)管理學(xué)ABC
A=催化劑(activator)
任何引發(fā)表現(xiàn)的原因
B=行為(behavior)
發(fā)生的表現(xiàn)
C=結(jié)果(consequence)
你對所產(chǎn)生表現(xiàn)的反應(yīng)
四種結(jié)果
1.沒有反應(yīng)
2.表示否定
3.調(diào)整指令
4.表示肯定
調(diào)整指令的方法
●盡可能快地、清晰而不帶責(zé)備地指出錯誤
●解釋錯誤的負(fù)面影響
●如果可以,將過錯歸結(jié)于沒有清楚地解釋工作任務(wù)
●詳細(xì)地重新解釋工作任務(wù),并確保對方已完全理解
●表達(dá)你對當(dāng)事人仍然充滿信任與信心
表揚(yáng)進(jìn)步
發(fā)現(xiàn)他們越做越好,即便做得不是完全正確,也要表揚(yáng)他們的進(jìn)步。通過這種方法,
你就將他們推上了成功之路,并使他們可以在那里繼續(xù)前進(jìn)
鯨魚哲學(xué)反應(yīng)
●立即表揚(yáng)別人
●具體指出他們哪些做得對,哪些做得基本正確
●與他們分享你對于他們所做工作的積極感覺
●鼓勵他們繼續(xù)好好工作
貓捉老鼠
發(fā)現(xiàn)別人做的錯事
鯨魚哲學(xué)
發(fā)現(xiàn)別人做得正確的事情
當(dāng)一切進(jìn)展順利的時候,
清醒點(diǎn),
說點(diǎn)表示肯定的話!
無論什么時候,只要你批評了別人的行為或是給了對方一個否定的反饋,不管你多么
小心地去措辭,結(jié)果都會破壞或削弱你與他之間的關(guān)系。如果你不斷地這樣做,你就會徹底毀了這種關(guān)系。他們會對你失去信任并開始用同樣的方法對待你。
首先,不需要被其他人激勵而做事情的人只有企業(yè)家,他們要么擁有自己的生意,要么是為自己工作的自由職業(yè)者。他們是自覺的,而且他們的目標(biāo)與整個組織的目標(biāo)是聯(lián)系在一起的。事實上,他們個人的目標(biāo)通常與組織的目標(biāo)是相同的。其他任何人——雇員、家里的孩子,或者是海洋世界的鯨魚——被要求做的事情都是組織需要他們?nèi)プ龅氖虑?,而且是那些如果讓他們自己選擇,他們可能會選擇不做的事情。
即使是鯨魚哲學(xué)反應(yīng)本身也不是最終目的,它只是幫助人們實現(xiàn)‘發(fā)現(xiàn)自己做得正確的事情’這一最終目標(biāo)的手段。
擁有權(quán)利是一件了不起的事情,但是不要利用它。你能夠真正讓人們做你想讓他們做的事情的惟一途徑,就是與他們建立起一種積極的、信任的關(guān)系。對人要及時肯定,這樣你就會得到積極的結(jié)果。
如今,任何新的經(jīng)營舉措,不論是技術(shù)還是服務(wù)的革新,抑或是價格戰(zhàn)略,都會立刻被別人知曉并被
抄襲。也就是說,你僅有的、真正可競爭的空間只是你與員工的關(guān)系。如果他們信任、尊重你,并相信你制定的目標(biāo),他們就會想方設(shè)法去取悅你的顧客。一旦你擁有了這些,再加上你的一些其他優(yōu)勢,比如產(chǎn)品質(zhì)量、價格和市場營銷以及送貨上門等等,那就沒有人能夠戰(zhàn)勝你了。你與下屬的關(guān)系,以及下屬與顧客之間的關(guān)系,任何競爭對手都永遠(yuǎn)無法從你這里偷走,只有這一樣?xùn)|西是你惟一擁有的。
規(guī)則就是,永遠(yuǎn)不要以為你知道可以激勵別人的東西是什么。
鯨魚哲學(xué)只有在你
真誠和誠實的時候才會奏效
一些“鯨魚哲學(xué)”反應(yīng)
在工作中
對管理人員:
你在會上提出的建議十分出色。你設(shè)計的開場白是為了引起人們的注意,我果然看到A女士在你說到XX的時候,神情很振奮。你在那么短的時間內(nèi)所做的一切非常有助于客戶對我們樹立信心。你的話給我們所有人都增了光。繼續(xù)好好干吧!
對一個工作團(tuán)隊:
咱們這個組在融洽合作與履行責(zé)任方面都非常出色。在接任本組的領(lǐng)導(dǎo)工作期間,是你們幫助我轉(zhuǎn)換了
角色,讓我從老板變成了協(xié)調(diào)人。我更喜歡這樣的角色。希望我們這個團(tuán)隊繼續(xù)好好工作。
對一個做出貢獻(xiàn)的個人:
我很欣賞你在報告中自創(chuàng)的數(shù)字分組的方式,這樣更容易看清結(jié)果。我想推薦所有人從現(xiàn)在開始都使用
你的方法。期待你今后想出更多的好主意。
對十幾歲的兒子:
我真高興回家看到你把車庫打掃干凈了。我原打算這個周六自己干這活兒,沒想到你提前做了。這下我
可以放松放松,干點(diǎn)別的了。你讓我松了口氣,巴德,非常感謝你!
對一個剛上一年級的孩子:
早上我剛叫你一遍你就起床了。當(dāng)時我們都在忙著收拾東西各自上路,你知道你一叫就起幫了我多少忙
嗎?非常多!
對一個十二歲的女兒:
我非常喜歡在開車送你去運(yùn)動和上課的路上跟你聊天。聽你說你和你朋友們的事情真有趣。我希望在你
成長的過程中我們還能繼續(xù)這樣的交談。
對一個學(xué)齡前兒童:
你沒用別人幫忙就自己系好了鞋帶、選好了要穿的衣服,真是棒極了!繼續(xù)努力。我真為你感到驕傲。
一些調(diào)整指令反應(yīng)
在工作中
●比爾,我知道你在使用新的結(jié)算系統(tǒng)時遇到了麻煩,我準(zhǔn)備讓貝蒂幫你一把。(一段時間后)干得不
錯,比爾。你交上來的報告說明你在使用這套系統(tǒng)方面已經(jīng)成了佼佼者。如果你有什么問題盡管告訴我。
●我們希望在這個項目上,每個人的才干都可以最大限度地發(fā)揮出來,埃利森。這就是我把你派到喬治
那一組去的原因。在那里,他們會用上你所有的技術(shù)。(一段時間后)祝賀你,埃利森。我早就知道你是跟喬治那一組工作的最佳人選。我非常欣賞你的工作。
在家里
(孩子沒有好好喂寵物。)
我現(xiàn)在不讓你喂寵物了,去用吸塵器打掃衛(wèi)生吧。我知道你喜歡做這項家務(wù),而且房間也確實該打掃了。(一段時間后)經(jīng)過你的打掃,這房子看起來真漂亮!
(孩子們正在因為看電視而吵鬧。)
為了讓每個人都滿意,我們需要為看電視制定一個計劃。(一段時間后)我真高興你們兩個能按照那天
我們在廚房里制定的計劃看電視!
posted @
2005-08-17 14:06 Dave 閱讀(1314) |
評論 (2) |
編輯 收藏
Reflection combines with effective object-oriented design to allow programs to be more flexible. Delegation is useful because it allows an object to change behavior at runtime. This change in behavior happens when one delegate that provides one behavior is replaced with another delegate that provides a different behavior. The number of different delegates available defines the amount that this behavior can vary.
Without reflective mechanisms, the number of delegates is limited to only the set of classes that are included in the system at comple time. Reflection increases this range of variation by allowing the system to use classes that are written later. There are several noteworthy aspects of this relationship:
posted @
2005-08-17 10:41 Dave 閱讀(89) |
評論 (0) |
編輯 收藏
public class MainApplication {
private Properties props;
private CustomerDatabase custDB;
public synchronized CustomerDatabase createDBFacade() {
if (custDB == null) {
try {
String dbClassName = props.getProperty("db.class",
"com.wci.app.StubCustomerDB");
Class cls = Class.forName(dbClassName);
custDB = (CustomerDatabase) cls.newInstance();
} catch (ClassNotFoundException ex) {
// ...
} catch (InstantiationException ex) {
// ...
} catch (IllegalAccessException ex) {
// ...
}
}
return custDB;
}
}
posted @
2005-08-17 10:11 Dave 閱讀(98) |
評論 (0) |
編輯 收藏
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
public class Driver {
public static Document serializeObject(Object source) throws Exception {
return serializeHelper(source, new Document(new Element("serialized")),
new IdentityHashMap());
}
private static Document serializeHelper(Object source, Document target,
Map table) throws Exception {
String id = Integer.toString(table.size());
table.put(source, id);
Class sourceclass = source.getClass();
Element oElt = new Element("object");
oElt.setAttribute("class", sourceclass.getName());
oElt.setAttribute("id", id);
target.getRootElement().addContent(oElt);
if (!sourceclass.isArray()) {
Field[] fields = Mopex.getInstanceVariables(sourceclass);
for (int i = 0; i < fields.length; i++) {
if (!Modifier.isPublic(fields[i].getModifiers()))
fields[i].setAccessible(true);
Element fElt = new Element("field");
fElt.setAttribute("name", fields[i].getName());
Class declClass = fields[i].getDeclaringClass();
fElt.setAttribute("declaringclass", declClass.getName());
Class fieldtype = fields[i].getType();
Object child = fields[i].get(source);
if (Modifier.isTransient(fields[i].getModifiers())) {
child = null;
}
fElt.addContent(serializeVariable(fieldtype, child, target,
table));
oElt.addContent(fElt);
}
} else {
Class componentType = sourceclass.getComponentType();
int length = Array.getLength(source);
oElt.setAttribute("length", Integer.toString(length));
for (int i = 0; i < length; i++) {
oElt.addContent(serializeVariable(componentType, Array.get(
source, i), target, table));
}
}
return target;
}
private static Element serializeVariable(Class fieldtype, Object child,
Document target, Map table) throws Exception {
if (child == null) {
return new Element("null");
} else if (!fieldtype.isPrimitive()) {
Element reference = new Element("reference");
if (table.containsKey(child)) {
reference.setText(table.get(child).toString());
} else {
reference.setText(Integer.toString(table.size()));
serializeHelper(child, target, table);
}
return reference;
} else {
Element value = new Element("value");
value.setText(child.toString());
return value;
}
}
}
===============================
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
public class Mopex {
public static Method getSupportedMethod(Class cls, String name,
Class[] paramTypes) throws NoSuchMethodException {
if (cls == null) {
throw new NoSuchMethodException();
}
try {
return cls.getDeclaredMethod(name, paramTypes);
} catch (NoSuchMethodException ex) {
return getSupportedMethod(cls.getSuperclass(), name, paramTypes);
}
}
public static Field[] getInstanceVariables(Class cls) {
List accum = new LinkedList();
while (cls != null) {
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (!Modifier.isStatic(fields[i].getModifiers())) {
if (!Modifier.isPublic(fields[i].getModifiers()))
fields[i].setAccessible(true);
accum.add(fields[i]);
}
}
cls = cls.getSuperclass();
}
Field[] retvalue = new Field[accum.size()];
return (Field[]) accum.toArray(retvalue);
}
}
===============================
public class Animal {
private String name;
private String gender;
private String classification;
private int weight;
public Animal(String name,String gender, String classification, int weight) {
super();
this.classification = classification;
this.gender = gender;
this.name = name;
this.weight = weight;
}
}
==============================
import java.util.ArrayList;
import java.util.List;
public class Zoo {
private String city;
private String name;
public Zoo(String name, String city) {
this.city = city;
this.name = name;
}
List animals = new ArrayList();
public void add(Animal panda1) {
animals.add(animals);
}
}
=========================
import org.jdom.Document;
import org.jdom.output.XMLOutputter;
public class ZooTest {
public static void main(String[] args) {
Animal panda1 = new Animal("Tian Tian", "male",
"Ailuropoda melanoleuca", 271);
Animal panda2 = new Animal("Mei Xiang", "female",
"Ailuropoda melanoleuca", 221);
Zoo national = new Zoo("National Zoological Park", "Washington, D.C.");
national.add(panda1);
national.add(panda2);
try {
XMLOutputter out = new XMLOutputter();
Document d = Driver.serializeObject(national);
out.output(d, System.out);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
posted @
2005-08-17 09:35 Dave 閱讀(162) |
評論 (0) |
編輯 收藏