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 閱讀(171) |
評論 (0) |
編輯 收藏
http://www.sergiopereira.com/articles/prototype.js.html
posted @
2006-08-10 15:06 Dave 閱讀(215) |
評論 (0) |
編輯 收藏
http://blog.csdn.net/calvinxiu/archive/2006/08/08/1036306.aspx
posted @
2006-08-10 13:02 Dave 閱讀(181) |
評論 (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)組成。普通字符包括大小寫的字母和數(shù)字,而元字符則具有特殊的含義,我們下面會給予解釋。
元字符 | ? | 描述 |
---|
| |
|
. | | 匹配任何單個字符。例如正則表達式r.t匹配這些字符串:rat、rut、r 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或多個正好在它之前的那個字符。例如正則表達式.*意味著能夠匹配任意數(shù)量的任何字符。 |
\ | | 這是引用府,用來將這里列出的這些元字符當作普通的字符來進行匹配。例如正則表達式\$被用來匹配美元符號,而不是行尾,類似的,正則表達式\.用來匹配點字符,而不是任何字符的通配符。 |
[ ]? [c1-c2] [^c1-c2] | | 匹配括號中的任何一個字符。例如正則表達式r[aou]t匹配rat、rot和rut,但是不匹配ret。可以在括號中使用連字符-來指定字符的區(qū)間,例如正則表達式[0-9]可以匹配任何數(shù)字字符;還可以制定多個區(qū)間,例如正則表達式[A-Za-z]可以匹配任何大小寫字母。另一個重要的用法是“排除”,要想匹配除了指定區(qū)間之外的字符——也就是所謂的補集——在左邊的括號和第一個字符之間使用^字符,例如正則表達式[^269A-Z] 將匹配除了2、6、9和所有大寫字母之外的任何字符。 |
\< \> | | 匹配詞(word)的開始(\<)和結束(\>)。例如正則表達式\<the能夠匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:這個元字符不是所有的軟件都支持的。 |
\( \) | | 將 \( 和 \) 之間的表達式定義為“組”(group),并且將匹配這個表達式的字符保存到一個臨時區(qū)域(一個正則表達式中最多可以保存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\} | | 匹配指定數(shù)目的字符,這些字符是在它之前的表達式定義的。例如正則表達式A[0-9]\{3\} 能夠匹配字符"A"后面跟著正好3個數(shù)字字符的串,例如A123、A348等,但是不匹配A1234。而正則表達式[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)更加復雜。以前,該語言具有兩種類型 —— 引用類型和基本類型。對于引用類型,類型 和類 的概念基本上可以互換,術語子類型 和子類 也可以互換。
隨著泛型的引入,類型和類之間的關系變得更加復雜。List<Integer>
和 List<Object>
是不同的類型,但是卻是相同的類。盡管 Integer
擴展 Object
,但是 List<Integer>
不是 List<Object>
,并且不能賦給 List<Object>
或者強制轉換成 List<Object>
。
另一方面,現(xiàn)在有了一個新的古怪的類型叫做 List<?>
,它是 List<Integer>
和 List<Object>
的父類。并且有一個更加古怪的 List<? extends Number>
。類型層次的結構和形狀也變得復雜得多。類型和類不再幾乎是相同的東西了。
extends 的新含意
在 Java 語言引入泛型之前,extends
關鍵字總是意味著創(chuàng)建一個新的繼承自另一個類或接口的類或接口。
引入泛型之后,extends
關鍵字有了另一個含意。將 extends
用在類型參數(shù)的定義中(Collection<T extends Number>
)或者通配符類型參數(shù)中(Collection<? extends Number>
)。
當使用 extends
來指示類型參數(shù)限制時,不需要子類-父類關系,只需要子類型-父類型關系。還要記住,有限制類型不需要是該限制的嚴格子類型;也可以是 該限制。換句話說,對于 Collection<? extends Number>
,您可以賦給它 Collection<Number>
(盡管 Number
不是 Number
的嚴格子類型)和 Collection<Integer>
、Collection<Long>
、Collection<Float>
等等。
在任何這些含意中,extends
右邊的類型都可以是參數(shù)化類型(Set<V> extends Collection<V>
)。
posted @
2005-08-24 11:36 Dave 閱讀(192) |
評論 (0) |
編輯 收藏
Eclipse 運行命令行參數(shù)大全
包括英文版本和中文版本兩種的說明, 特別需要值得一提的是那個 -nl 參數(shù), 可以指定程序啟動時所使用的語言. 例如:
eclipse -nl en_US
將啟動英文語言, 這個特性在安裝了國際化語言包以后特別有用, 可以方便的切換各個語言的版本. 注意 IBM WSAD v5.1 也支持這個功能.
運行 Eclipse
將 Eclipse 驅動程序安裝(解壓縮)到某個目錄(例如,c:\eclipse)中之后,通過運行頂級安裝目錄中的 Eclipse 可執(zhí)行文件來啟動"工作臺"。在 Windows 系統(tǒng)上,該可執(zhí)行文件稱為 eclipse.exe,而在 Linux 系統(tǒng)上稱為 eclipse。注意:下列討論描述 Windows 系統(tǒng)上的設置。Linux 上的設置是相似的。
如果您沒有另行指定,則平臺將缺省工作區(qū)目錄創(chuàng)建為可執(zhí)行文件的兄弟目錄(例如 c:\eclipse\workspace)。此工作區(qū)目錄用作項目的缺省內(nèi)容區(qū),還用于保存任何必需的元數(shù)據(jù)。要進行共享安裝或多工作區(qū)安裝,應明確指出工作區(qū)的位置而不是使用缺省值。有兩種控制工作區(qū)位置的方法:使用當前工作目錄或使用 -data 命令行自變量。
將工作區(qū)位置設置為在當前工作目錄內(nèi)
在此方案中,工作區(qū)位置將是當前工作目錄中稱為 workspace 的目錄。
實現(xiàn)此目的最容易的方法可能是使用下列步驟來創(chuàng)建快捷方式:
導航到 Windows 資源管理器中的 eclipse.exe 并使用右鍵拖動來創(chuàng)建 eclipse.exe 的快捷方式。
編輯快捷方式的屬性,以使啟動位置:字段標識工作區(qū)位置的父目錄(例如,c:\users\robert)。
關閉屬性對話框并雙擊快捷方式(如果提供的目錄為 c:\users\robert,則工作區(qū)位置將為 c:\users\robert\workspace)。
當然,您也可以使用命令提示符(通過將目錄切換為工作區(qū)父目錄然后運行 eclipse.exe)來獲得同樣的效果。
使用 -data 設置工作區(qū)的特定位置
要使用 -data 命令行自變量,只要將 -data your_workspace_location(例如,-data c:\users\robert\myworkspace)添加至快捷方式屬性中的目標字段或顯式地將它包括在命令行上。
使用 -vm 設置 java VM
建議顯式指定在運行 Eclipse 時要使用哪個 Java VM。使用 -vm 命令行自變量(例如,-vm c:\jre\bin\javaw.exe)可以實現(xiàn)此目的。如果不使用 -vm,則 Eclipse 將使用在 O/S 路徑上找到的一個 Java VM。當安裝其它產(chǎn)品時,它們可更改您的路徑,導致在下一次啟動 Eclipse 時使用另一 Java VM。
運行 Eclipse 中的高級主題
Eclipse 可執(zhí)行文件及平臺本身提供了人們感興趣的開發(fā)或調試 Eclipse 各部件的許多執(zhí)行選項。運行 Eclipse 可執(zhí)行文件的一般格式是:
eclipse [platform options] [-vmargs [Java VM arguments]]
Eclipse 啟動參數(shù) 命令 描述 原因
-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 平臺的工作區(qū)的路徑。工作區(qū)位置也是項目的缺省位置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-debug [optionsFile]
將平臺置于調試方式,并從給定位置處的文件裝入調試選項(如果指定的話)。此文件指示哪些調試點可用于插件以及是否已啟用它們。如果未給出文件位置,則平臺在啟動 eclipse 的目錄中查找稱為".options"的文件。URL 和文件系統(tǒng)路徑都可作為文件位置。 1.0
-dev [classpathEntries]
將平臺置于開發(fā)方式。將可選類路徑條目(用逗號分隔的列表)添加至每個插件的運行時類路徑。例如,當工作區(qū)包含要開發(fā)的插件時,指定 -dev bin 會為每個插件項目的名為 bin 的目錄添加類路徑條目,允許在其中存儲最新生成的類文件。除去了冗余或不存在的類路徑條目。 1.0
-endsplash params
用于在 Eclipse 平臺啟動并運行時關閉閃屏的內(nèi)部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0
-feature featureId
主要功能部件的標識。主要功能部件為 Eclipse 的已啟動實例提供了產(chǎn)品個性,并確定使用的產(chǎn)品定制信息。 2.0
-keyring keyringFilePath
磁盤上授權數(shù)據(jù)庫(或"密鑰環(huán)"文件)的位置。此自變量必須與 -password 選項配合使用。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-nl locale
定義 Eclipse 平臺在其上運行的語言環(huán)境的名稱。Eclipse 平臺通常自動計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getNL() 用于插件。示例值有:"en_US"和"fr_FR_EURO"。 2.0
-nolazyregistrycacheloading
取消激活裝入優(yōu)化的平臺插件注冊表高速緩存。缺省情況下,僅當需要時才從注冊表高速緩存(可用時)中裝入擴展的配置元素,以減少內(nèi)存占用。此選項將在啟動時強制完全裝入注冊表高速緩存。 2.1
-noregistrycache
繞過讀寫內(nèi)部插件注冊表高速緩存文件。 2.0
-nosplash
運行平臺而不顯示閃屏。 1.0
-os operatingSystem
定義 Eclipse 平臺在其上運行的操作系統(tǒng)。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getOS() 用于插件,并用于解析插件清單文件中提及的路徑中 $os$ 變量的出現(xiàn)。示例值有:"win32"、"linux"、"hpux"、"solaris"和"aix"。 1.0
-password password
授權數(shù)據(jù)庫的密碼。與 -keyring 選項配合使用。 1.0
-perspective perspectiveId
啟動時要在活動工作臺窗口中打開的透視圖。如果沒有指定該參數(shù),則將打開關閉時活動的透視圖。 1.0
-plugincustomization propertiesFile
包含插件首選項缺省設置的屬性文件的位置。這些缺省設置覆蓋在主要功能部件中指定的缺省設置。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 2.0
-plugins pluginsFileURL
(建議不使用;用 -configuration 代替;支持 1.0 兼容)。 指定 Eclipse 平臺查找插件的文件的位置,表示為 URL。該文件為屬性文件格式,其中鍵是任意用戶定義名稱,值是指向 plugin.xml 文件的顯式路徑或指向包含插件的目錄的路徑的用逗號分隔的列表。注意,不允許使用相對 URL。如果指定此項,則此選項會導致創(chuàng)建適當?shù)呐R時配置。 *1.0
-refresh
啟動時執(zhí)行工作區(qū)的全局刷新的選項。這將使從上次平臺運行以來在文件系統(tǒng)中所做的任何更改一致。 1.0
-showlocation
用于在窗口標題欄中顯示工作區(qū)的位置的選項。在發(fā)行版 2.0 中,此選項僅與 -data 命令行自變量一起使用。 2.0
-showsplash params
用于顯示閃屏(由可執(zhí)行的 Eclipse 平臺啟動器執(zhí)行)的內(nèi)部選項。此選項在閃屏處理鏈中不同的位置有不同的語法和語義。 2.0
-vm vmPath
要用來運行 Eclipse 平臺的"Java 運行時環(huán)境"(JRE)的位置。如果不指定此項,則 JRE 位于 jre(它是 Eclipse 可執(zhí)行文件的兄弟目錄)。相對于從中啟動 eclipse 的目錄來解釋相對路徑。 1.0
-ws windowSystem
定義 Eclipse 平臺在其上運行的 Windows 系統(tǒng)。Eclipse 平臺通常使用 Java os.name 屬性的常用值來計算最佳設置。如果在此處指定該項,則這是 Eclipse 平臺使用的值。此處指定的值可作為 BootLoader.getWS() 用于插件、用于配置 SWT 以及用于解析插件清單文件中提及的路徑中 $ws$ 變量的出現(xiàn)。示例值有:"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 可執(zhí)行文件以內(nèi)部方式自動設置的參數(shù),必須指定 -vmargs 不帶任何參數(shù),如下所示:
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 設置適合進行初期研究工作,但在進行大型開發(fā)時是不夠的。對于大型開發(fā),應修改 VM 自變量以使有更多的堆可用。例如,下列設置將允許 Java 堆增大為 256MB:
posted @
2005-08-22 10:49 Dave 閱讀(215) |
評論 (0) |
編輯 收藏
愛因斯坦曾經(jīng)說:“任何事情都應該越簡單越好,而不是比較簡單。”實際上,科學真理的目的就是在假設的前提下去簡化一個理論,這樣,人們可以去關注真正重要的問題。在企業(yè)軟件開發(fā)中,道理是一樣的。
簡化企業(yè)軟件開發(fā)的一個關鍵是,提供一個這樣的應用框架:它可以使開發(fā)人員不用關注于很多復雜的問題,比如事務處理、安全和持久化等。一個設計良好的框架將提升代碼的可復用性,提高開發(fā)者的效率,并得到更高質量的軟件。然而,目前J2EE 1.4下的EJB 2.1 框架被廣泛認為是設計較差而且過度復雜的。不滿足于EJB2.1框架,JAVA開發(fā)者使用了很多其他的中間件服務產(chǎn)品。最值得關注的是,以下兩個框架吸引了大量開發(fā)者的興趣和積極反饋。這兩個框架很可能成為未來企業(yè)JAVA應用開發(fā)框架的選擇。
Spring框架是一個廣受歡迎的但是非標準的開源框架。它主要由Interface21公司開發(fā)和控制。Spring框架的體系結構是基于注射依賴(DI)模式。Spring框架使用了大量的XML配置文件,它可以獨立應用,或者在現(xiàn)有的應用服務器上工作。
EJB 3.0框架是JCP定義的并且被所有主流J2EE提供商支持的標準框架。EJB 3.0規(guī)范的預發(fā)布版本目前已經(jīng)有開源的和商業(yè)的實現(xiàn),如JBOSS和ORACLE。EJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能。譯者注)
這兩個框架有著一個共同的核心設計理念:它們的目標是為松耦合的POJO類提供中間件服務。框架通過在運行時截取執(zhí)行環(huán)境,或將服務對象注射給POJO類的方式,將應用服務和POJO類“連接”起來。POJO類本身并不關注如何“連接”,而且也很少依賴于框架。這樣,開發(fā)者可以將注意力集中在業(yè)務邏輯上,可以對他們的POJO類進行與框架無關的單元測試。并且,由于POJO類不需要繼承框架的類或實現(xiàn)框架提供的接口,開發(fā)者可以在更加靈活性的基礎上構建繼承體系,和搭建應用。
盡管有著共同的理念,但這兩個框架采取了不同的方式來提供POJO服務。由于已經(jīng)出版了大量的比較Spring與EJB2.1或者EJB3.0與EJB2.1的書籍和文章,而沒有關于比較Spring和EJB3.0的認真研究,因此,本文將考察它們之間幾個關鍵的不同,討論他們優(yōu)缺點。本文談到的主題同樣適用于其他不太有名的但同樣提供“松耦合POJO” 設計的企業(yè)中間件框架。我希望,這篇文章可以幫助你選者最合適的你需求的框架。
提供商無關性
開發(fā)者選擇JAVA平臺的一個最重要的原因就是它的提供廠商無關性。EJB 3.0是一個被設計為對提供商沒有依賴性的開放的標準。EJB 3.0規(guī)范由企業(yè)JAVA社區(qū)的主流開源組織和廠商共同編寫和支持的。EJB 3.0框架使開發(fā)者的應用程序實現(xiàn)可以獨立于應用服務器。比如,JBoss的EJB 3.0的實現(xiàn)是基于Hibernate的,Oracle的EJB 3.0實現(xiàn)是基于TopLink的,但是,在JBoss或者Oracle上跑應用程序,開發(fā)者既不需要去學習Hibernate,也不需要學習TopLink提供的獨特API。廠商無關性使EJB 3.0框架區(qū)別于當前其他任何的POJO中間件框架。
然而,就象很多EJB 3.0的批評者很快指出的一樣,目前EJB 3.0規(guī)范正在編寫還未完全完成最終發(fā)布版。很有可能,還需要1至2年,EJB 3.0才會被主流J2EE廠商完全接受。但是,就算你的應用服務器本身不支持EJB 3.0,你也可以通過下載和安裝一個“可嵌入的” EJB 3.0產(chǎn)品,來使你的應用服務器支持EJB 3.0應用。比如,JBoss“可嵌入的” EJB 3.0產(chǎn)品是開源的,它可以運行在任何兼容J2SE-5.0環(huán)境下(如你的應用服務器),目前處于Beta版測試中。其他廠商同樣可以快速發(fā)布他們自己的可嵌入EJB 3.0產(chǎn)品,特別是規(guī)范中“數(shù)據(jù)持久化”部分。
另一方面,Spring一直是一個非標準的技術,而且在可以預計的未來仍將如此。盡管你在任何應用服務器都上可以使用Spring框架,但基于Spring的應用仍然被限制于Spring本身和在你的應用中使用到的Spring提供的各種特別服務。
由于Spring框架是一個開源項目,因此,它使用的配置文件XML格式和開發(fā)接口都是私有的。當然,這種限制不僅體現(xiàn)在Spring框架中,其他任何非標準產(chǎn)品都會有這種限制。但是,你的Spring應用的長期生存能力將依賴于Spring項目本身(或者說Interface 21公司,因為它雇傭了大多數(shù)的Spring核心開發(fā)人員)。并且,如果你使用了Spring提供的特殊服務,如Spring事務管理器或者Spring MVC,你同樣被限制于Spring提供的API。
并且,Spring應用是知道后端服務提供者的(即應用程序是知道服務提供者的,這樣應用程序將會在一定程度上依賴于服務提供方:譯者注)。例如,對于數(shù)據(jù)持久化服務,Spring框架提供了不同的DAO和模板Helper類,用于JDBC、Hibernate,、iBatis和JDO。這樣,假如你需要改變一個Spring應用的持久化服務提供者(如,從JDBC換到Hibernate),你將需要重構你的系統(tǒng)應用代碼,來使用新的Helper類。
服務整合 Spring框架是建立在應用服務器和服務庫之上,它的服務整合代碼(如數(shù)據(jù)訪問模板和Helper類)是基于框架的,并暴露給應用開發(fā)者。相反,EJB 3.0框架是緊密整合到應用服務器中的,它的服務整合代碼是封裝在一個標準的接口下的。
因此,EJB 3.0廠商可以輕松的優(yōu)化整體性能和開發(fā)者體驗。如,在JBoss的EJB 3.0實現(xiàn)中,當你通過實體管理器持久化一個實體BEAN POJO時,Hibernate session事務將在JTA事務提交時自動提交。通過使用簡單的@PersistenceContext注解(例子參看后面文章),你可以甚至可以將實體管理器和其下的Hibernate事務綁定到一個有狀態(tài)的session bean上。應用程序事務可以在一個session中跨越多個線程,在事務性的WEB應用中這是非常有用的,如多頁面的購物車。
基于EJB 3.0 框架、Hibernate、和JBoss 內(nèi)部Tomcat的緊密整合,上面提到的簡單的整合的編程接口是可能的。Oracle的EJB 3.0框架和它內(nèi)部的Toplink持久服務可以達到同樣層次的整合。
EJB 3.0中整合服務的另一個好例子是集群支持。假如你部署一個EJB 3.0應用到一個集群服務器,所有的故障切換、負載均衡、分布式緩存、和狀態(tài)復制服務對于應用程序來說,都是自動完成的。集群服務被隱藏在EJB 3.0編程接口之下,對于EJB 3.0開發(fā)者來說,這些服務都是完全透明的。
在Spring中,優(yōu)化框架和服務之間交互更加困難一些。例如,想要用Spring的聲明式事務服務來管理Hibernate事務,必須在XML配置文件中明確的配置Spring的事務管理器(TransactionManager)和Hibernate SessionFactory對象。Spring應用開發(fā)者必須自己管理跨越多個HTTP請求的事務。并且,沒有簡單的方法可以在Spring應用中實現(xiàn)集群服務
服務聚合的靈活性 由于Spring中的服務整合代碼是作為編程接口暴露給應用開發(fā)者的,因此開發(fā)人員可以根據(jù)需要來聚合多個服務。這個特性使你可以集成一個你自己的“輕量”級應用服務器。Spring的一個通常的用法是將Tomcat和Hibernate連接起來來支持簡單的數(shù)據(jù)庫驅動的WEB應用程序。在這種情況下,Spring本身提供了事務管理服務,Hibernate提供了持久化服務,這種設置本身就創(chuàng)建了一個小型的應用服務器。
通常,EJB 3.0應用服務器不提供給開發(fā)者這種按照你的需要來選擇服務的靈活性。大多數(shù)情況,你會得到一系列已經(jīng)預先打包好的特性,其中有些你可能是不需要的。然而,如果應用服務器提供了模塊內(nèi)部的獨特設計,就象JBOSS一樣,你可以不去關心這些不必要的特性。在任何情況下,去定制一個全功能的應用服務器并不是一個瑣碎而沒有意義的工作。
當然,如果一個應用不是一個單一的結點,你將需要連接多個應用服務器提供的服務(如資源池、消息隊列和集群)。這種情況下,從總的資源消耗上看,Spring框架就和任何EJB 3.0方案一樣是“重量級”的。
為了進行容器外的單元測試,Spring的靈活的服務聚合也可以來連接假對象,來替代真的服務對象。在EJB 3.0應用中,大多數(shù)的組件都是簡單POJO,他們可以容易進行容器外的單元測試。但是,如果要測試與容器服務相關的服務對象(如持久化實體管理器),更好的方式是進行容器內(nèi)的測試,因為這樣比使用假對象來替代的方式更加容易,更加健壯,而且更加準確。
XML vs. 注解
從應用開發(fā)者的角度來看,Spring的編程接口主要基于XML配置文件,而EJB 3.0則大量的使用了JAVA注解。XML文件可以表達復雜的關系,但是它們更加冗長而且不健壯。注解的方式很簡單明了,但是很難去表達復雜的或者繼承性的結構。
Spring和EJB 3.0分別選擇了XML和注解方式,這取決于框架的體系結構:由于注釋只能描述相當少的配置信息,只有一個預先整合好的框架(如大多數(shù)重要事情已經(jīng)在框架中實現(xiàn)了)才能大量的使用注釋作為它的配置選項。象我們討論的一樣,EJB 3.0滿足了這些要求,而Spring作為一個一般的注射依賴框架,它沒有做到這一點。
當然,由于EJB 3.0和Spring相互學習了很多特性,所以,它們都在某種層次上支持XML和注釋。例如,EJB 3.0中可以應用XML配置文件來作為一個選擇性的機制,用來改變注釋的默認行為。注釋也可以用來配置一些Spring服務。
研究XML和注釋直接區(qū)別的最好的方式就是通過例子。在下面的幾節(jié)中,我們將一起看一下EJB 3.0和Spring是如何為應用程序提供關鍵服務的。
聲明式服務 EJB 3.0和Spring都將運行時服務(如事務管理、安全、日志、消息、和信息服務)連接給應用程序。由于這些服務同應用程序的業(yè)務邏輯并不是直接相關的,因此,它們不被應用程序本身來管理。相反,這些服務被服務容器(如EJB 3.0和Spring)以不可見的方式在運行時提供給應用程序。開發(fā)人員(或系統(tǒng)管理員)通過配置來告訴容器什么時候,以怎樣的方式來應用這些服務。
EJB 3.0通過JAVA注解的方式來配置聲明式服務,Spring則通過XML配置文件來完成。大多數(shù)情況下,EJB 3.0 的注解方式是應用這種服務的更加簡單和優(yōu)美的方式。下面是一個在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指定代碼屬性和配置聲明服務將導致冗長的和不桅頂?shù)呐渲梦募O旅媸荢pring應用中一個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類增加的攔截器的數(shù)量程幾何增長。意識到了僅使用XML配置文件的限制性,Spring支持在JAVA源代碼中使用Apache Commons metadata來指定事物屬性。在最新的Spring 1.2中,JDK-1.5風格的注釋也被支持。為了使用事務元數(shù)據(jù),你需要為上面例子中的AttributesTransactionAttributeSource 改變一個transactionAttributeSource bean,并且增加一個附加的對元數(shù)據(jù)攔截器的設置。
<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元數(shù)據(jù)簡化了transactionAttributeSource元素。但是它沒有解決XML配置文件的根本問題:仍然需要冗長的、易錯的事務攔截器,事務管理器,和事務屬性。
注射依賴
中間件容器的一個主要優(yōu)點是它們使得程序開發(fā)人員可以去構建松耦合的應用程序。服務使用者僅僅需要知道服務接口就可以使用服務。容器把具體的服務實現(xiàn)實例化,然后將它們提供給服務使用者。這樣,容器可以在可替換的服務實現(xiàn)之間進行切換,而不改變服務接口和服務使用者代碼。
注射依賴模式是實現(xiàn)松耦合應用程序的一個最好的方式。比起以前的方式,如通過JNDI進行查找或回調容器,注射依賴模式更容易使用,而且更加優(yōu)美。使用注射依賴模式,框架扮演了構建服務的對象工廠角色,然后根據(jù)運行時的配置,把這些服務對象注射到應用程序的POJO類中。從程序開發(fā)人員的角度看,作為客戶端使用者的POJO在需要使用服務對象前就自動的得到了它們。
Spring 和 EJB 3.0都提供了大量的DI模式支持。但是,它們之間也有著根本的不同。Spring支持了通常意義上的但是復雜的基于XML配置文件的注射依賴API;EJB 3.0支持的注射大多數(shù)通用服務對象(如,EJB和容器對象)和JNDI對象,它通過簡單的JAVA注解來完成。
EJB 3.0的注射注解相當?shù)暮啙嵰子谩?#64;Resource標簽注射大多數(shù)的通過服務對象和JNDI對象。下面的例子顯示了如何將JNDI提供的服務器缺剩數(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方法注射給使用者。應用程序不用顯示的調用setter方法,在任何其他方法被調用前容器將調用setter方法完成注射。
@Resource
public void setSessionContext (SessionContext ctx) {
sessionCtx = ctx;
}
對于更復雜的服務對象,還有一些特殊的注射注解。例如,@EJB 注解被用來注射EJB stubs,@PersistenceContext注解被用來注射實體管理器對象,這些對象負責處理EJB 3.0實體Bean的數(shù)據(jù)訪問操作。 下面的例子給出如何將一個實體管理器注射到一個有狀態(tài)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 規(guī)范定義了可以通過注解來被注射使用的服務器資源。但是,它不支持用戶自定義的POJO類之間的相互注射。
在Spring中,為了將服務對象注射到你的POJO類中,你首先需要定義一個setter方法(或有參數(shù)的構造函數(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);
}
}
因此,你可以指定容器如何得到這個服務,并且在運行時通過配置文件中XML元素的連接關系把它提供給POJO。下面的例子顯示了連接一個數(shù)據(jù)源到一個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的目標都是提供企業(yè)服務,使得POJO可以松耦合,但是它們實現(xiàn)的方式非常不同。在兩個框架中注射依賴模式都有大量的應用。
通過EJB 3.0的標準方式、大量應用的注解、還有同應用服務器緊密整合性,這些提供了更高的廠商無關性和開發(fā)人員工作效率。Spring的以XML為中心的配置文件和注射依賴的連貫使用,允許開發(fā)人員去構造更加靈活的應用系統(tǒng),并且可以同時與多個應用服務提供者同時工作。
感謝
作者感謝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,而實現(xiàn)對EJB緩存的控制。
?? client-deployer-service.xml:部署J2EE應用客戶。
?? ear-deployer.xml:部署J2EE EAR應用。
?? ejb-deployer.xml:部署J2EE EJB應用。
?? hsqldb-ds.xml:設置嵌入式Hypersonic數(shù)據(jù)庫服務,并將其作為默認數(shù)據(jù)源。
?? 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實現(xiàn)。
?? jboss-ws4ee.sar:提供J2EE Web服務支持。
?? jbossjca-service.xml:JBoss JCA實現(xiàn),使得在JBoss中部署JCA資源適配器成為可能。
?? jbossweb-tomcat50-sar:含有嵌入式Tomcat服務的展開SAR文件。它為JBoss提供了標準的Web容器。
?? jms:將JMS相關的服務聚集在一起,并放置在jms目錄中。
?? hsqldb-jdbc-state-service.xml:使用HSQLDB管理狀態(tài)。
?? hsqldb-jdbc2-service.xml:使用嵌入式HSQL數(shù)據(jù)庫實現(xiàn)緩存和持久化。它還包含了JMS實現(xiàn)的核心服務,即DestinationManager MBean。
?? jbossmq-destinations-service.xml:供JBoss測試套件使用的JMS Topic和Queue。
?? jbossmq-service.xml:JMS其他服務,包括攔截器配置。
?? jms-ds.xml:將JBoss消息實現(xiàn)作為默認JMS提供商。并且,它還提供JCA配置信息,以供集成JBoss JCA和JMS資源適配器使用。
?? jms-ra.rar:資源適配器,供JCA處理JMS連接工廠使用。
?? jbossmq-httpil.sar:提供JMS調用層,從而實現(xiàn)HTTP方式使用JMS。
?? jvm-il-service.xml:配置本地JMS傳輸調用層,供本地JVM使用JMS。
?? uil2-service.xml:配置JMS版本2統(tǒng)一調用層。這是一種可靠的、自定義的、基于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:配置警告監(jiān)聽器,比如控制臺監(jiān)聽器、E_mail監(jiān)聽器,等等。
?? properties-service.xml:設置JVM的全局系統(tǒng)屬性(由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、有狀態(tài)會話Bean復制、CMP2緩存有效性服務。
?? deploy-hasingleton-service.xml:HASingletonDeployer MBean。用于確保群集中只有單個節(jié)點在deploy-hasingleton目錄部署了服務。
?? deploy.last/farm-service.xml:farm群集部署服務。用于確保它在所有其他服務部署之后才部署其本身。
?? ebxmlrr-service.xml:JAXR注冊服務實現(xiàn)。
?? iiop-service.xml:實現(xiàn)對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) |
編輯 收藏
目錄結構:
?? bin:含有啟動、停止以及其他系統(tǒng)相關腳本。在前面,本書已經(jīng)討論過啟動JBoss應用服務器的run腳本。
?? client:存儲供Java客戶應用或者外部Web容器使用的配置文件和JAR文件。用戶可以使用所需要的具體存檔,或者僅僅使用jbossall-client.jar。
?? docs:含有JBoss引用的XML DTD文件(當然,還包括JBoss具體配置文件)。同時,還存在JCA(Java Connetor Architecture,Java連接器架構)實例配置文件,供設置不同數(shù)據(jù)庫的數(shù)據(jù)源使用(比如MySQL、Oracle、Postgres)。
?? lib:包含運行JBoss微內(nèi)核所需的JAR文件。請注意,不要往該目錄添加用戶自身的任何JAR文件。
?? server:包含的各個子目錄都是不同的服務器配置。通過往run腳本后添加-c <config name>參數(shù)便能夠指定不同的配置。接下來,來看看default服務器配置。
從根本上考慮,JBoss架構是由JMX MBean服務器、微內(nèi)核、一套可插入式組件服務以及MBean構成的。這種架構使得,集成不同的配置變得更加簡單,并且能夠很靈活地滿足用戶的各自需求。用戶不再需要一次性運行重量級的應用服務器。同時,用戶可以刪除不再需要使用的組件(這將從很大程度上減少服務器的啟動時間),并且通過開發(fā)自己的MBean還能夠集成其他服務到JBoss中。當然,如果是運行標準J2EE應用,則不用理會這些自定義工作。用戶所需要的一切服務,JBoss發(fā)布版都包括了。
server目錄下存在3個服務器實例配置:all、default以及minimal,它們各自提供了不同的服務集合。很顯然,如果啟動JBoss服務器時沒有指定其他配置,則將使用default配置。
minimal:這是啟動JBoss服務器所要求的最低配置。minimal配置將啟動日志服務、JNDI服務器以及URL部署掃描器,以找到新的部署應用。對于那些不需要使用任何其他J2EE技術,而只是使用自定義服務的場合而言,則這種JMX/JBoss配置最適合。它僅僅是服務器,而不包含Web容器、不提供EJB和JMS支持。
?? default:默認配置,它含有大部分J2EE應用所需的標準服務。但是,它不含有JAXR服務、IIOP服務、或者其他任何群集服務。
?? all:提供了所有可用的服務。它包含RMI/IIOP和群集服務,default配置中沒有提供群集服務。
用戶也可以添加自身的服務器配置。最佳做法是,拷貝最接近用戶需求的現(xiàn)有配置,然后修改其具體內(nèi)容。比如,如果用戶不需要使用消息服務,則只需要拷貝default目錄,并重新命名為myconfig,然后刪除jms子目錄。最后,啟動myconfig配置。
run -c myconfig
default服務器配置目錄的具體內(nèi)容:
conf:含有指定JBoss核心服務的jboss-service.xml文件。同時,還包括核心服務的其他配置文件。
?? data:Hypersonic數(shù)據(jù)庫實例將數(shù)據(jù)存儲在此處。JBossMQ(JMS的JBoss實現(xiàn))也使用它存儲消息。
?? deploy:用戶將應用代碼(JAR\WAR\EAR文件)部署在此處。同時,deploy目錄也用于熱部署服務(即,那些能夠從運行服務器動態(tài)添加或刪除的服務)和部署JCA資源適配器。因此,用戶能夠在deploy目錄看到大量的配置文件。尤其是,用戶能夠看到JMX控制臺應用(未打包的WAR文件),本書前面討論過。JBoss服務器將定期掃描該目錄,從而查找是否有組件更新或修改,從而自動完成組件的重新部署。本書后續(xù)章節(jié)將詳細闡述部署細節(jié)。
?? lib:服務器配置所需的JAR文件。用戶可以添加自身的庫文件,比如JDBC驅動,等等。
?? log:日志信息將存儲到該目錄。JBoss使用Jakarta Log4j包作為其日志功能。同時,用戶可以在應用中直接使用Log4j日志記錄功能。
?? tmp:供部署器臨時存儲未打包應用使用,也可以作為其他用途。
?? work:供Tomcat編譯JSP使用。
其中,data、log、tmp、work目錄是JBoss創(chuàng)建的。如果用戶沒有啟動過JBoss服務器,則這些目錄不會被創(chuàng)建。
.
2.2.1 核心服務
當JBoss服務器啟動時,首先會啟動conf/jboss-service.xml文件指定的核心服務。
雖然通過conf/jboss-service.xml文件能夠添加其他MBean服務,但是更好的辦法是,將單獨的配置文件放置在deploy目錄中,因為這將使得用戶的服務具有熱部署能力。
2.2.2 日志服務
Log4j是JBoss使用的日志功能包。通過conf/log4j.xml文件能夠控制JBoss的日志功能。
2.2.3 安全性服務
安全性域信息存儲在login-config.xml文件中,其包含了許多安全性域定義。各個安全性域指定了許多JAAS登陸模塊,供安全性域認證使用。當用戶需要在應用中使用安全性時,需要在JBoss特定部署描述符jboss.xml或jboss-web.xml中指定待使用的安全性域名。
2.2.4 其他服務
deploy目錄放置的服務不是核心服務,但具有熱部署能力。用戶可以通過XML描述符文件(*-service.xml)或JBoss服務存檔(SAR)文件給出服務。SAR同時含有XML描述符和服務所要求的其他資源(比如,類、JAR庫文件以及其他存檔),而且SAR是以單個存檔文件給出的。
posted @
2005-08-19 17:47 Dave 閱讀(914) |
評論 (2) |
編輯 收藏
投資是一種追求未來貨幣增值的經(jīng)濟行為。
新中國的第一張股票: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) |
編輯 收藏
建立信任
及時給予肯定
出錯時調整注意力
表現(xiàn)管理學ABC
A=催化劑(activator)
任何引發(fā)表現(xiàn)的原因
B=行為(behavior)
發(fā)生的表現(xiàn)
C=結果(consequence)
你對所產(chǎn)生表現(xiàn)的反應
四種結果
1.沒有反應
2.表示否定
3.調整指令
4.表示肯定
調整指令的方法
●盡可能快地、清晰而不帶責備地指出錯誤
●解釋錯誤的負面影響
●如果可以,將過錯歸結于沒有清楚地解釋工作任務
●詳細地重新解釋工作任務,并確保對方已完全理解
●表達你對當事人仍然充滿信任與信心
表揚進步
發(fā)現(xiàn)他們越做越好,即便做得不是完全正確,也要表揚他們的進步。通過這種方法,
你就將他們推上了成功之路,并使他們可以在那里繼續(xù)前進
鯨魚哲學反應
●立即表揚別人
●具體指出他們哪些做得對,哪些做得基本正確
●與他們分享你對于他們所做工作的積極感覺
●鼓勵他們繼續(xù)好好工作
貓捉老鼠
發(fā)現(xiàn)別人做的錯事
鯨魚哲學
發(fā)現(xiàn)別人做得正確的事情
當一切進展順利的時候,
清醒點,
說點表示肯定的話!
無論什么時候,只要你批評了別人的行為或是給了對方一個否定的反饋,不管你多么
小心地去措辭,結果都會破壞或削弱你與他之間的關系。如果你不斷地這樣做,你就會徹底毀了這種關系。他們會對你失去信任并開始用同樣的方法對待你。
首先,不需要被其他人激勵而做事情的人只有企業(yè)家,他們要么擁有自己的生意,要么是為自己工作的自由職業(yè)者。他們是自覺的,而且他們的目標與整個組織的目標是聯(lián)系在一起的。事實上,他們個人的目標通常與組織的目標是相同的。其他任何人——雇員、家里的孩子,或者是海洋世界的鯨魚——被要求做的事情都是組織需要他們?nèi)プ龅氖虑椋沂悄切┤绻屗麄冏约哼x擇,他們可能會選擇不做的事情。
即使是鯨魚哲學反應本身也不是最終目的,它只是幫助人們實現(xiàn)‘發(fā)現(xiàn)自己做得正確的事情’這一最終目標的手段。
擁有權利是一件了不起的事情,但是不要利用它。你能夠真正讓人們做你想讓他們做的事情的惟一途徑,就是與他們建立起一種積極的、信任的關系。對人要及時肯定,這樣你就會得到積極的結果。
如今,任何新的經(jīng)營舉措,不論是技術還是服務的革新,抑或是價格戰(zhàn)略,都會立刻被別人知曉并被
抄襲。也就是說,你僅有的、真正可競爭的空間只是你與員工的關系。如果他們信任、尊重你,并相信你制定的目標,他們就會想方設法去取悅你的顧客。一旦你擁有了這些,再加上你的一些其他優(yōu)勢,比如產(chǎn)品質量、價格和市場營銷以及送貨上門等等,那就沒有人能夠戰(zhàn)勝你了。你與下屬的關系,以及下屬與顧客之間的關系,任何競爭對手都永遠無法從你這里偷走,只有這一樣東西是你惟一擁有的。
規(guī)則就是,永遠不要以為你知道可以激勵別人的東西是什么。
鯨魚哲學只有在你
真誠和誠實的時候才會奏效
一些“鯨魚哲學”反應
在工作中
對管理人員:
你在會上提出的建議十分出色。你設計的開場白是為了引起人們的注意,我果然看到A女士在你說到XX的時候,神情很振奮。你在那么短的時間內(nèi)所做的一切非常有助于客戶對我們樹立信心。你的話給我們所有人都增了光。繼續(xù)好好干吧!
對一個工作團隊:
咱們這個組在融洽合作與履行責任方面都非常出色。在接任本組的領導工作期間,是你們幫助我轉換了
角色,讓我從老板變成了協(xié)調人。我更喜歡這樣的角色。希望我們這個團隊繼續(xù)好好工作。
對一個做出貢獻的個人:
我很欣賞你在報告中自創(chuàng)的數(shù)字分組的方式,這樣更容易看清結果。我想推薦所有人從現(xiàn)在開始都使用
你的方法。期待你今后想出更多的好主意。
對十幾歲的兒子:
我真高興回家看到你把車庫打掃干凈了。我原打算這個周六自己干這活兒,沒想到你提前做了。這下我
可以放松放松,干點別的了。你讓我松了口氣,巴德,非常感謝你!
對一個剛上一年級的孩子:
早上我剛叫你一遍你就起床了。當時我們都在忙著收拾東西各自上路,你知道你一叫就起幫了我多少忙
嗎?非常多!
對一個十二歲的女兒:
我非常喜歡在開車送你去運動和上課的路上跟你聊天。聽你說你和你朋友們的事情真有趣。我希望在你
成長的過程中我們還能繼續(xù)這樣的交談。
對一個學齡前兒童:
你沒用別人幫忙就自己系好了鞋帶、選好了要穿的衣服,真是棒極了!繼續(xù)努力。我真為你感到驕傲。
一些調整指令反應
在工作中
●比爾,我知道你在使用新的結算系統(tǒng)時遇到了麻煩,我準備讓貝蒂幫你一把。(一段時間后)干得不
錯,比爾。你交上來的報告說明你在使用這套系統(tǒng)方面已經(jīng)成了佼佼者。如果你有什么問題盡管告訴我。
●我們希望在這個項目上,每個人的才干都可以最大限度地發(fā)揮出來,埃利森。這就是我把你派到喬治
那一組去的原因。在那里,他們會用上你所有的技術。(一段時間后)祝賀你,埃利森。我早就知道你是跟喬治那一組工作的最佳人選。我非常欣賞你的工作。
在家里
(孩子沒有好好喂寵物。)
我現(xiàn)在不讓你喂寵物了,去用吸塵器打掃衛(wèi)生吧。我知道你喜歡做這項家務,而且房間也確實該打掃了。(一段時間后)經(jīng)過你的打掃,這房子看起來真漂亮!
(孩子們正在因為看電視而吵鬧。)
為了讓每個人都滿意,我們需要為看電視制定一個計劃。(一段時間后)我真高興你們兩個能按照那天
我們在廚房里制定的計劃看電視!
posted @
2005-08-17 14:06 Dave 閱讀(1316) |
評論 (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) |
編輯 收藏
想在企業(yè)階梯中順利地一階一階往上爬?「今日管理」(Management Today)
雜誌日前指出,工作者應該注意幾個獲得升遷的秘訣:
1.願意多做一些。願意主動多做一些工作,可以贏得同事的感激,也顯示
了你已經(jīng)準備好承擔更多的工作職責。
2.積極建立人際網(wǎng)路。無論公司內(nèi)外,你認識的人越多,獲得新職務的機
會就越大。
3.執(zhí)行深入細節(jié),但是看法擴及整體。讓別人覺得你會思考公司的重要議
題,謹慎選擇適合的議題,表達你對該議題的看法。
4.熱情具有傳染性。展現(xiàn)出你對公司的熱情及忠誠,如果你的活力可以影
響其他人,公司會希望讓你扮演更重要的角色。
5.協(xié)助會議更順利進行。在會議中發(fā)揮助攻效果,顯示出你的獨特之處,
並且與別人建立更好的關係。
6.避免一般的事業(yè)生涯發(fā)展途徑。明天的領導人需要的經(jīng)驗,可能與今天
的領導人不同,特別的事業(yè)生涯發(fā)展經(jīng)歷,可以讓你在同事中鶴立雞群。
7.幾年更改一次職責。讓你保持對工作的新鮮感,也給予你更廣博的經(jīng)驗
,增加競爭力。
8.有焦點,但也具彈性。決定自己想要的職務,想要的工作技能,以及你
將如何獲得它們,目標明確,但是也願意接受出現(xiàn)的新機會。
posted @
2005-08-16 09:30 Dave 閱讀(100) |
評論 (0) |
編輯 收藏
The class diagrams are essentially the same, but the two patterns differ in their
intent.
With the State Pattern, we have a set of behaviors encapsulated in state objects; at any time the context is delegating to one of those states. Over time, the current state changes across the set of state objects to reflect the internal state of the context, so the context's behavior echanges over time as well. The client usually knows very little, if anything, about the state objects.
With Strategy, the client usually specifies the strategy object that the context is composed with. Now, while the pattern provides the flexibility to change the strategy object at runtime, often there is a strategy object that is most appropriate for a context object.
In general, think of the Strategy Pattern as a flexible alternative to subclassing; if you use inheritance to define the behavior of a class, then you're stuck with that behavior even if you need to change it. With Stategy you can change the behavior by composing with a defferent object.
Think of the State Pattern as an alternative to putting lots of conditionals in your context; by encapsulating the behaviors within state objects, you can simply change the state object in context to change its behavior.
posted @
2005-08-15 14:13 Dave 閱讀(106) |
評論 (0) |
編輯 收藏
職員為什么跳槽?是嫌錢少,還是嫌職位低?最大的原因是“我討厭這個老板!”因為不滿老板而跳槽,因為喜歡經(jīng)理就投奔,看來,“攻心為上”這句名言千古不變。如果你能留住并且不斷吸引人才,就說明你是一位出色的管理者。
一定程度的人員流動是不可避免的,它向企業(yè)進步和招聘新的優(yōu)秀人才敞開了大門,使企業(yè)能夠充滿活力。然而,過多的人員流失將不可避免地導致企業(yè)松散和成本增加。突然而來的意外人員變更將會對客戶服務和公司運營造成重創(chuàng)。
所有這些問題的關鍵在哪里?答案卻是出人意料的簡單。公平合理的補償和個人發(fā)展的機會常常是非常重要的因素,然而大多數(shù)員工離開公司卻是因為另外一個原因:令人生厭的老板。
員工不是離開公司,他們是離開老板
國外最近對20000名剛剛離開老板的員工進行了一項調查,調查發(fā)現(xiàn),落后的監(jiān)督管理方式是員工辭職的主要原因。員工留在公司時間的長短,很大程度上取決于他和經(jīng)理的關系好壞,如果他們的關系不好,就很難得到晉升的機會。
來自蓋洛普的測驗顯示,75%雇員的離職是離開他們的主管而非公司。在一家跨國公司200名離職人員中,只有40人在離職時進行了薪酬談判,其中27人因公司加薪留了下來,這27人中又有25人在1年后仍然選擇了離開,他們中大多數(shù)人離開的理由就是“令人討厭的上司”。
美國的一項研究報告也顯示,員工當初如果以薪酬為理由向公司提出辭職,在他們離開公司3至6個月后跟蹤離職面談中,這一原因往往會讓位于其他主導原因,出現(xiàn)頻率最高的便是“對主管不滿”。很多人當初加盟某個單位的主要原因,是沖著該公司在社會上的知名度和在該行業(yè)里的主導地位。當分配到某個部門后,日常工作中更多的將是直接面對該部門經(jīng)理,作為員工的頂頭上司,如果該部門經(jīng)理不是非常優(yōu)秀,或者該部門工作對公司全局沒有重要性,部門業(yè)務未見大的起色,那么部門內(nèi)的員工就會士氣低落,時間一長,優(yōu)秀人才必然會萌生去意,另尋其他更好的發(fā)展機會。
除了主管要求員工超量、超時工作、獨攬大權外,引起員工對主管不滿的還有主管任命隨心所欲,傷了員工的心;主管制造內(nèi)耗,惡化團隊工作;主管不以身作則,常常以身試法;主管任人唯親,排斥異己等原因。
至于“主管問題”為何會被離職人員隱藏起來,一是員工自己心里不愿承認或者接受是因與主管關系不和而導致自己辭職的事實;二是提出辭職后,像放行日期、有關薪酬的結算以及今后其他企業(yè)前來進行背景調查都可能和主管有關系,自己的命運還掌握在主管手中;此外就是怕暴露出自己人際關系處理能力的薄弱,影響將來的求職等。這些都導致員工會尋找另外的原因來作為離職的理由。許多雇員流動或薪資調研報告中,人際關系在雇員流動原因中排在第五位后,導致“主管問題”沒有受到管理層的足夠重視。
與其費力留人才,不如先培養(yǎng)優(yōu)秀經(jīng)理
公司如何才能留住員工?從更廣的范圍來說,如何才能提高生產(chǎn)效率和激發(fā)工人的工作熱情?
通過培養(yǎng)個人和公司的關系,使員工對公司有一種家的感覺,其中包括個人的責任具體化、遠期學習的機會和大量的非正式的、不拘束的信息反饋和交流。完成這項工作幾乎總是從同員工直接接觸的第一線的經(jīng)理開始。現(xiàn)在是讓經(jīng)理們負起責任的時候了。
不少人力資源專家都一致贊同這樣一個觀點:雇員真正想要的,常常是那些經(jīng)理簡單就能給與的東西。
防止員工流失工作的公司,應該把重點放在使工作吸引人和對經(jīng)理的培訓上,要把他們培養(yǎng)成有魄力、靈活和富于觀察的經(jīng)理。讓我們看看國際知名公司的成功經(jīng)驗。
開放式溝通交流——Container Store公司是以達拉斯為基地的一家著名零售商。它被財富雜志評為全美國最優(yōu)秀的工作場所。這里的人員流動率只有20%,而大多數(shù)的零售業(yè)中的人員流動率通常在80%-120%之間。
第一年,該公司全職員工要接受大約235小時的培訓,并且向他們提供正式和非正式的與經(jīng)理互動交流的機會。經(jīng)理不但要讓員工知道做好工作的注意事項,并且還要定期接受培訓,如何為員工提供必要的援助。以經(jīng)理主管領導層所稱的“直接溝通”經(jīng)營管理哲學為指導原則,公司的兩千多名員工定期討論公司銷售額、公司目標和遠景計劃等,在確保開放和溝通的環(huán)境中闊步向前。
胡蘿卜比大棒有用——金融服務業(yè)的巨頭美國萬國寶通銀行也開始對經(jīng)理進行培訓,使他們知道如何成為被公司視為作用“日漸重要”的員工們的良師益友。這些經(jīng)理常常十分樂于使用內(nèi)部晉升的激勵制度,激發(fā)員工的自信心和成就感,特別是在員工想另謀高就時能夠留住人心。
成為員工的良師益友——Autodesk Inc.是位于加利福尼亞San Rafael的一家著名電腦軟件公司。其人力資源專家和培訓專家最近設計了一項關于員工保持力的網(wǎng)上培訓計劃,經(jīng)理們經(jīng)過培訓之后將會掌握一定的技巧,運用這些技巧可以了解員工的個人事業(yè)目標,成為技能嫻熟的職業(yè)顧問。在特定時期內(nèi),他們可以根據(jù)實際情況制定一個同時適用于公司和員工的具體發(fā)展計劃,這樣的雙贏局面自然會吸引很多想在職業(yè)上有所發(fā)展的員工。
留不住人,就讓經(jīng)理對員工流失負責
如何確實讓經(jīng)理們對下屬員工的流動負起責任?
這里還有一個簡單而有效的方法,可以鼓勵和幫助經(jīng)理們降低人員的流動性:把他們的福利補償和員工的流動率聯(lián)系起來。如果保持了較低的流動率,那么就對他們進行獎勵。反之,如果摩擦不斷,員工離職率很高則對他們進行處罰。這是一個很行之有效的戰(zhàn)術手段,但是還有待于大家的廣泛關注。
大多數(shù)經(jīng)理都很討厭把他們的收入和其他的因素聯(lián)系起來。但是,越來越多的公司正在認識到員工的去留關鍵在于他們的經(jīng)理。這種事實正在被大家廣泛的實踐,因為大多數(shù)的保留員工的計劃在實施的時候都簡單易行且成本很低。當然,使經(jīng)理們接受贊同員工保留計劃和方法并不那么一帆風順。一些人說他們所做的努力對改變現(xiàn)在人員流動的現(xiàn)狀的影響力太小。另外一些人則認為這將耗費他們太多的時間。但是,如果人力資源工作人員能夠給他們開始這項工作的機會、把他們引導到正確的方向上來,并且向他們展示和說明留住優(yōu)秀人才他們完全能夠做得到,完全能夠控制得了,那么經(jīng)理們就會開始工作。
通過聯(lián)合最優(yōu)秀的人才,并給他們分派有意義的工作、給他們提供發(fā)展機會和晉升的機會,經(jīng)理能夠成為更出色的老板。這是一個在競爭中生存的問題。
posted @
2005-08-15 13:21 Dave 閱讀(83) |
評論 (0) |
編輯 收藏
A hook is a method that is declared in the abstract class, but only give an empty or default implementation. This gives subclasses the ability to "hook into" the algorithm at various points, if they wish; a subclass is also free to ignore the hook.
posted @
2005-08-15 09:55 Dave 閱讀(142) |
評論 (0) |
編輯 收藏
生命是一種過程。
事情的結果盡管重要,但是做事情的過程更加重要,因為結果好了我們會更加快樂,但過程使我們的生命充實。人的生命最后的結果一定是死亡,我們不能因此說我們的生命沒有意義。世界上很少有永恒。戀愛中的人們每天都在信誓旦旦地說我會愛你一輩子,這實際上是不真實的。最真實的說法是:“我今天,此時此刻正在真心地愛著你。” 明天也許你會失戀,失戀后我們會體驗到失戀的痛苦。這種體驗也是豐富你生命的一個過程。
兩點之間最短的距離并不一定是直線。
在人與人的關系以及做事情的過程中,我們很難直截了當就把事情做好。我們有時需要等待,有時需要合作,有時需要技巧。我們做事情會碰到很多困難和障礙,有時候我們并不一定要硬挺、硬沖,我們可以選擇有困難繞過去,有障礙繞過去,也許這樣做事情更加順利。大家想一想,我們和別人說話還得想想哪句話更好聽呢?尤其現(xiàn)在這個比較復雜的社會中,大家要學會想辦法諒解別人,要讓人覺得你這個人很成熟,很不錯,你才能把事情做成。
只有知道如何停止的人才知道如何加速。
我有位朋友在學滑雪的時候,最大的體會就是停不下來。他剛開始學滑雪時沒有請教練,看著別人滑雪,覺得很容易,不就是從山頂滑到山下嗎?于是他穿上滑雪板,赤溜一下就滑下去了,結果他從山頂滑到山下,實際上是滾到山下,摔了很多個跟斗。他根本就不知道怎么停止、怎么保持平衡。經(jīng)過反覆練習,終于學會了在任何坡上停止、滑行、再停止。這個時候他就發(fā)現(xiàn)自己會滑雪了,就敢從山頂高速地往山坡下沖。因為他知道只要想停,一轉身就能停下來。只要你能停下來,你就不會撞上樹、撞上石頭、撞上人,你就不會被撞死。因此,只有知道如何停止的人,才知道如何高速前進。
放棄是一種智慧,缺陷是一種恩惠。
當你擁有六個蘋果的時候,千萬不要把它們都吃掉,因為你把六個蘋果全都吃掉,你也只吃到了六個蘋果,只吃到了一種味道,那就是蘋果的味道。如果你把六個蘋果中的五個拿出來給別人吃,盡管表面上你丟了五個蘋果,但實際上你卻得到了其他五個人的友情和好感。以后你還能得到更多,當別人有了別的水果的時候,也一定會和你分享,你會從這個人手里得到一個橘子,那個人手里得到一個梨,最后你可能就得到了六種不同的水果,六種不同的味道,六種不同的顏色,六個人的友誼。人一定要學會用你擁有的東西去換取對你來說更加重要和豐富的東西。所以說,放棄是一種智慧。做人最大的樂趣在于通過奮斗去獲得我們想要的東西,有缺點意味著我們可以進一步完美,有匱乏之處意味著我們可以進一步努力。
決定行動,行動產(chǎn)生結果。誰都能做夢想家,只有行動才能體現(xiàn)時間的價值。我要珍惜生命中的時光,我將立即開始行動!
posted @
2005-08-12 13:27 Dave 閱讀(78) |
評論 (0) |
編輯 收藏
楊修終于被曹操殺了,楊修覺得死得冤,死得太不值了,所以他的魂魄不愿投胎。等啊等,有一天,他見到了曹操的亡魂,急忙上前問道:"明公慢走,你當初為什么要殺我?"曹操一看是楊修,便停住了腳步,笑了一下,答道:"你想知道我為什么要殺你嗎?聽我慢慢道來。你的智力過人,非常聰明,你上知天文,下查地理,懂奇門,會八卦,可以說是一個奇才。但是你恰恰忘記學習一門人生的必修課,那就是領導者的心態(tài)。所以你不曉人和。今天閑著也是閑著,我給你補上這一課。
領導,作為一個成功人士來講,曾經(jīng)遭受過多少坎坷,又遭受過多少艱辛,還遭受過多少他人的冷眼,你知道嗎?在創(chuàng)業(yè)階段流過多少汗,淌過多少淚,吃過多少苦,你知道嗎?成功后又承受著多大的壓力,面對著多大的困難,忍受著多大的指責,你知道嗎?他們不缺錢花,也不缺衣穿,唯獨缺少的就是他人的認可,希望的是別人來贊美他幾句,哪怕是唯心的,起碼讓他覺得他的努力沒有白費。而現(xiàn)實呢,沒有人這么做,他們招來的只有嫉妒的目光和無窮的排擠。這些你知道嗎?孤獨是領導者的難言之隱,他們不敢奢求其他人來贊美他,讓自己的下屬贊美一下,這個要求過分嗎?不過分!一點兒都不過分!但是你,楊修,沒有做到,相反處處和我作對。記得有一次我拿給你們一盒點心,只不過想讓你們來和我說一聲想吃,我不會不給你們吃的,興許我還會多給你們幾盒。我在盒上寫了'一合酥',意思就是讓你們不知道其中的含義,而來向我請教,然后我會告訴你們,'合'字下面沒有'皿',也就是說,沒有東西盛放,你們無法吃,我把盤子給你們,你們不就能吃了嗎,這樣顯得我既聰明,又和藹,有什么不好,可是你偏要把它理解為'一人一口酥',全給我吃掉了,你說,當時我的面子往哪兒擱啊,我的心里能平衡嗎?不能!
記得有一次,好像是工人修一座門,問我是寬一些還是窄一些好,我身材較胖,當然想讓門寬一些,但是我要是如果這么直說,顯得我太沒有水平了,于是我靈機一動,在門上寫了一個'活'字,同'門'字合在一起就是個'闊'字。有話不明說,這是領導顯示其尊嚴的一種手段,當人們無法猜出的時候,我再給予解答,你知道嗎,這樣的感覺是多么多么的爽嗎?然而,就是因為你,楊修,我沒有爽成,反到讓你爽了一下,你毫不留情的把謎底給我揭穿了,你知道后來他們說我什么嗎,他們說:'我們的丞相怎么這么愛賣弄啊,簡單的事非要搞復雜了。'你讓我的尊嚴蕩然無存,我能不恨你嗎?
我要在我的兩個兒子中選出一個來繼承我的大業(yè),曹丕和曹植都是可造之材,我有心考核一下他們的能力,這是關系到我的千秋大業(yè)的事情,結果你,楊修,偏要給曹植出謀劃策,嚴重影響了我對他們績效考核的真實性,從而誤導了我的選擇方向,你罪不容誅!曹植的落選,和你有直接的關系,你難辭其咎!你的魔爪已伸向了我的家庭,破壞了我們的父子關系,你無情的撕下了我隱私的面紗,你太可恨了!
大家公認我愛才,求賢若渴也是我所追求的目標。當年,彌橫是多么的囂張,當眾脫光衣服,敲著鼓罵我,我沒有生氣;徐庶之母當眾數(shù)落我的不是,還用硯臺打我,我還是沒有生氣;我待關羽如同至親,上馬金,下馬銀,三日一大宴,五日一小宴,還把赤兔馬給他,但他還是棄我而去,我仍然沒有生氣。他們這些行為,我都可以忍,唯有你,楊修,讓我忍無可忍,你比他們更可恨一千倍,一萬倍,因為你是我的下屬,是我一手把你栽培到今天,所以你最可恨。那個時候,我就已經(jīng)暗下決心,要把你殺死,只是缺個機會而已。
我?guī)Пh中攻打劉備,久戰(zhàn)不勝,反而損兵折將,當時確有退意,可是我并沒有表態(tài),而你卻自作聰明,把我的口令'雞肋'引申為'食之無味,棄之可惜',說我要退兵,搞的軍中將士心無戰(zhàn)意,我被你逼的沒有選擇了。我真不明白我這個領導者在你面前,居然被你左右,你是我的領導,不,你是我的祖宗!不過這次你還不知道,你聰明到頭了,正好給了我殺你的機會,我不能錯過這個機會了,如果我錯過這次機會,今后在你面前,我永遠都是孫子。
我還是那句話,你的確很聰明,但正是你的小聰明,把你的性命害了,應了古訓,'聰明反被聰明誤'.你太愛耍小聰明,已達到了忘我的境界了。你眼里跟本就沒有'領導'這個概念。所有的人當中,就你敢拿領導'開涮',就你敢挑領導的毛病,就你敢違抗領導的命令。有句俗話,你應該知道,'老虎的屁股摸不得',你偏要摸,可想而知,你是在自尋死路!"楊修聽到這里,"撲通"一聲跪倒在地,"曹丞相,我服了,我楊修是生的窩囊,死的活該。我這輩子算是白活了,不過今天這節(jié)課補得好啊,我全明白了。時候也不早了,咱們一同去投胎吧,來世我還做您的下屬。"曹操哈哈大笑,挽著楊修的胳膊走向了奈何橋。但由于他們談話的時間太長了,比別人晚投了一千多年。
從此,人世間多了一對君臣:乾隆與和珅。
posted @
2005-08-12 13:19 Dave 閱讀(107) |
評論 (0) |
編輯 收藏
1. Both FM an AFM create objects. But FM do it through inheritance and AFM through object composition.
To create objects using FM, you need to extends a class and override a factory method. the whole point of the FM Pattern is that your're using a subclass to do your own creation for you. In that way, clients only need to know the abstract type they are using, the subclass worries about the concrete type. So, in other words, FM keep clients decoupled from the concrete types.
AFM provides an abstrct type for creating a family of products. Subclasses of this type define how those products are produced. To use the factory, your instantiate one and pass it into some code that is written against the abstract type. So, like FM, the clients are decoupled from the actual concrete products they use.
2. AFM group together a set of related products
3. AFM often use factory methods to implement it's concrete factories.
4. use AFM whenever you have families of products you need to create and you want to make sure your clients create products that belong together. use FM to decouple your client code from the concrete classes you need to instantiate, or if you don't know ahead of time all the concrete classes you are going to need , just subclass and implement the factory method.
posted @
2005-08-12 11:03 Dave 閱讀(156) |
評論 (0) |
編輯 收藏
1. No varible should hold a reference to a concrete class.
If you use new, you'll be holding a reference to a concrete class. Use a factory to get around that.
2. No class should derive from a concrete class.
If you derive from a concrete class, you're depending on a concrete class. Derive from an abstraction, like an interface or an abstraction class.
3. No method should override an implemented method of any of its base classes.
If you override an implented method, then your base class wasn't really an abstraction to start with. Those methods implemented in the base class are meant to be shared by all your subclasses.
posted @
2005-08-12 09:42 Dave 閱讀(88) |
評論 (0) |
編輯 收藏