作者: Michael Juntao Yuan
發(fā)表時(shí)間: 06/29/2005
發(fā)表于: http://www.
翻譯: 陳博
原作鏈接: http://www./pub/a/onjava/2005/06/29/spring-ejb3.html
愛因斯坦曾經(jīng)說:“任何事情都應(yīng)該越簡單越好,而不是比較簡單。”實(shí)際上,科學(xué)真理的目的就是在假設(shè)的前提下去簡化一個(gè)理論,這樣,人們可以去關(guān)注真正重要的問題。在企業(yè)軟件開發(fā)中,道理是一樣的。
簡化企業(yè)軟件開發(fā)的一個(gè)關(guān)鍵是,提供一個(gè)這樣的應(yīng)用框架:它可以使開發(fā)人員不用關(guān)注于很多復(fù)雜的問題,比如事務(wù)處理、安全和持久化等。一個(gè)設(shè)計(jì)良好的框架將提升代碼的可復(fù)用性,提高開發(fā)者的效率,并得到更高質(zhì)量的軟件。然而,目前J2EE 1.4下的EJB 2.1 框架被廣泛認(rèn)為是設(shè)計(jì)較差而且過度復(fù)雜的。不滿足于EJB2.1框架,JAVA開發(fā)者使用了很多其他的中間件服務(wù)產(chǎn)品。最值得關(guān)注的是,以下兩個(gè)框架吸引了大量開發(fā)者的興趣和積極反饋。這兩個(gè)框架很可能成為未來企業(yè)JAVA應(yīng)用開發(fā)框架的選擇。
Spring框架是一個(gè)廣受歡迎的但是非標(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è)的實(shí)現(xiàn),如JBOSS和ORACLE。EJB 3.0大量使用了JAVA注解(Java annotations,是JDK1.5提供的新功能。譯者注)
這兩個(gè)框架有著一個(gè)共同的核心設(shè)計(jì)理念:它們的目標(biāo)是為松耦合的POJO類提供中間件服務(wù)??蚣芡ㄟ^在運(yùn)行時(shí)截取執(zhí)行環(huán)境,或?qū)⒎?wù)對(duì)象注射給POJO類的方式,將應(yīng)用服務(wù)和POJO類“連接”起來。POJO類本身并不關(guān)注如何“連接”,而且也很少依賴于框架。這樣,開發(fā)者可以將注意力集中在業(yè)務(wù)邏輯上,可以對(duì)他們的POJO類進(jìn)行與框架無關(guān)的單元測試。并且,由于POJO類不需要繼承框架的類或?qū)崿F(xiàn)框架提供的接口,開發(fā)者可以在更加靈活性的基礎(chǔ)上構(gòu)建繼承體系,和搭建應(yīng)用。
盡管有著共同的理念,但這兩個(gè)框架采取了不同的方式來提供POJO服務(wù)。由于已經(jīng)出版了大量的比較Spring與EJB2.1或者EJB3.0與EJB2.1的書籍和文章,而沒有關(guān)于比較Spring和EJB3.0的認(rèn)真研究,因此,本文將考察它們之間幾個(gè)關(guān)鍵的不同,討論他們優(yōu)缺點(diǎn)。本文談到的主題同樣適用于其他不太有名的但同樣提供“松耦合POJO” 設(shè)計(jì)的企業(yè)中間件框架。我希望,這篇文章可以幫助你選者最合適的你需求的框架。
提供商無關(guān)性
開發(fā)者選擇JAVA平臺(tái)的一個(gè)最重要的原因就是它的提供廠商無關(guān)性。EJB 3.0是一個(gè)被設(shè)計(jì)為對(duì)提供商沒有依賴性的開放的標(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的實(shí)現(xiàn)是基于Hibernate的,Oracle的EJB 3.0實(shí)現(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的批評(píng)者很快指出的一樣,目前EJB 3.0規(guī)范正在編寫還未完全完成最終發(fā)布版。很有可能,還需要1至2年,EJB 3.0才會(huì)被主流J2EE廠商完全接受。但是,就算你的應(yīng)用服務(wù)器本身不支持EJB 3.0,你也可以通過下載和安裝一個(gè)“可嵌入的” 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一直是一個(gè)非標(biāo)準(zhǔn)的技術(shù),而且在可以預(yù)計(jì)的未來仍將如此。盡管你在任何應(yīng)用服務(wù)器都上可以使用Spring框架,但基于Spring的應(yīng)用仍然被限制于Spring本身和在你的應(yīng)用中使用到的Spring提供的各種特別服務(wù)。
由于Spring框架是一個(gè)開源項(xiàng)目,因此,它使用的配置文件XML格式和開發(fā)接口都是私有的。當(dāng)然,這種限制不僅體現(xiàn)在Spring框架中,其他任何非標(biāo)準(zhǔn)產(chǎn)品都會(huì)有這種限制。但是,你的Spring應(yīng)用的長期生存能力將依賴于Spring項(xiàng)目本身(或者說Interface 21公司,因?yàn)樗蛡蛄舜蠖鄶?shù)的Spring核心開發(fā)人員)。并且,如果你使用了Spring提供的特殊服務(wù),如Spring事務(wù)管理器或者Spring MVC,你同樣被限制于Spring提供的API。
并且,Spring應(yīng)用是知道后端服務(wù)提供者的(即應(yīng)用程序是知道服務(wù)提供者的,這樣應(yīng)用程序?qū)?huì)在一定程度上依賴于服務(wù)提供方:譯者注)。例如,對(duì)于數(shù)據(jù)持久化服務(wù),Spring框架提供了不同的DAO和模板Helper類,用于JDBC、Hibernate,、iBatis和JDO。這樣,假如你需要改變一個(gè)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ù)整合代碼是封裝在一個(gè)標(biāo)準(zhǔn)的接口下的。
因此,EJB 3.0廠商可以輕松的優(yōu)化整體性能和開發(fā)者體驗(yàn)。如,在JBoss的EJB 3.0實(shí)現(xiàn)中,當(dāng)你通過實(shí)體管理器持久化一個(gè)實(shí)體BEAN POJO時(shí),Hibernate session事務(wù)將在JTA事務(wù)提交時(shí)自動(dòng)提交。通過使用簡單的@PersistenceContext注解(例子參看后面文章),你可以甚至可以將實(shí)體管理器和其下的Hibernate事務(wù)綁定到一個(gè)有狀態(tài)的session bean上。應(yīng)用程序事務(wù)可以在一個(gè)session中跨越多個(gè)線程,在事務(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ù)的另一個(gè)好例子是集群支持。假如你部署一個(gè)EJB 3.0應(yīng)用到一個(gè)集群服務(wù)器,所有的故障切換、負(fù)載均衡、分布式緩存、和狀態(tài)復(fù)制服務(wù)對(duì)于應(yīng)用程序來說,都是自動(dòng)完成的。集群服務(wù)被隱藏在EJB 3.0編程接口之下,對(duì)于EJB 3.0開發(fā)者來說,這些服務(wù)都是完全透明的。
在Spring中,優(yōu)化框架和服務(wù)之間交互更加困難一些。例如,想要用Spring的聲明式事務(wù)服務(wù)來管理Hibernate事務(wù),必須在XML配置文件中明確的配置Spring的事務(wù)管理器(TransactionManager)和Hibernate SessionFactory對(duì)象。Spring應(yīng)用開發(fā)者必須自己管理跨越多個(gè)HTTP請求的事務(wù)。并且,沒有簡單的方法可以在Spring應(yīng)用中實(shí)現(xiàn)集群服務(wù)
服務(wù)聚合的靈活性
由于Spring中的服務(wù)整合代碼是作為編程接口暴露給應(yīng)用開發(fā)者的,因此開發(fā)人員可以根據(jù)需要來聚合多個(gè)服務(wù)。這個(gè)特性使你可以集成一個(gè)你自己的“輕量”級(jí)應(yīng)用服務(wù)器。Spring的一個(gè)通常的用法是將Tomcat和Hibernate連接起來來支持簡單的數(shù)據(jù)庫驅(qū)動(dòng)的WEB應(yīng)用程序。在這種情況下,Spring本身提供了事務(wù)管理服務(wù),Hibernate提供了持久化服務(wù),這種設(shè)置本身就創(chuàng)建了一個(gè)小型的應(yīng)用服務(wù)器。
通常,EJB 3.0應(yīng)用服務(wù)器不提供給開發(fā)者這種按照你的需要來選擇服務(wù)的靈活性。大多數(shù)情況,你會(huì)得到一系列已經(jīng)預(yù)先打包好的特性,其中有些你可能是不需要的。然而,如果應(yīng)用服務(wù)器提供了模塊內(nèi)部的獨(dú)特設(shè)計(jì),就象JBOSS一樣,你可以不去關(guān)心這些不必要的特性。在任何情況下,去定制一個(gè)全功能的應(yīng)用服務(wù)器并不是一個(gè)瑣碎而沒有意義的工作。
當(dāng)然,如果一個(gè)應(yīng)用不是一個(gè)單一的結(jié)點(diǎn),你將需要連接多個(gè)應(yīng)用服務(wù)器提供的服務(wù)(如資源池、消息隊(duì)列和集群)。這種情況下,從總的資源消耗上看,Spring框架就和任何EJB 3.0方案一樣是“重量級(jí)”的。
為了進(jìn)行容器外的單元測試,Spring的靈活的服務(wù)聚合也可以來連接假對(duì)象,來替代真的服務(wù)對(duì)象。在EJB 3.0應(yīng)用中,大多數(shù)的組件都是簡單POJO,他們可以容易進(jìn)行容器外的單元測試。但是,如果要測試與容器服務(wù)相關(guān)的服務(wù)對(duì)象(如持久化實(shí)體管理器),更好的方式是進(jìn)行容器內(nèi)的測試,因?yàn)檫@樣比使用假對(duì)象來替代的方式更加容易,更加健壯,而且更加準(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)少的配置信息,只有一個(gè)預(yù)先整合好的框架(如大多數(shù)重要事情已經(jīng)在框架中實(shí)現(xiàn)了)才能大量的使用注釋作為它的配置選項(xiàng)。象我們討論的一樣,EJB 3.0滿足了這些要求,而Spring作為一個(gè)一般的注射依賴框架,它沒有做到這一點(diǎn)。
當(dāng)然,由于EJB 3.0和Spring相互學(xué)習(xí)了很多特性,所以,它們都在某種層次上支持XML和注釋。例如,EJB 3.0中可以應(yīng)用XML配置文件來作為一個(gè)選擇性的機(jī)制,用來改變注釋的默認(rèn)行為。注釋也可以用來配置一些Spring服務(wù)。
研究XML和注釋直接區(qū)別的最好的方式就是通過例子。在下面的幾節(jié)中,我們將一起看一下EJB 3.0和Spring是如何為應(yīng)用程序提供關(guān)鍵服務(wù)的。
聲明式服務(wù)
EJB 3.0和Spring都將運(yùn)行時(shí)服務(wù)(如事務(wù)管理、安全、日志、消息、和信息服務(wù))連接給應(yīng)用程序。由于這些服務(wù)同應(yīng)用程序的業(yè)務(wù)邏輯并不是直接相關(guān)的,因此,它們不被應(yīng)用程序本身來管理。相反,這些服務(wù)被服務(wù)容器(如EJB 3.0和Spring)以不可見的方式在運(yùn)行時(shí)提供給應(yīng)用程序。開發(fā)人員(或系統(tǒng)管理員)通過配置來告訴容器什么時(shí)候,以怎樣的方式來應(yīng)用這些服務(wù)。
EJB 3.0通過JAVA注解的方式來配置聲明式服務(wù),Spring則通過XML配置文件來完成。大多數(shù)情況下,EJB 3.0 的注解方式是應(yīng)用這種服務(wù)的更加簡單和優(yōu)美的方式。下面是一個(gè)在EJB 3.0中對(duì)一個(gè)POJO的方法使用事務(wù)管理服務(wù)的例子。
public class Foo {
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public bar () {
// do something ...
}
}
你可以對(duì)一段代碼聲明多個(gè)屬性,并應(yīng)用多個(gè)服務(wù)。下面是一個(gè)對(duì)EJB 3.0中POJO類同時(shí)使用事務(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)用中一個(gè)XML元素的例子,它用來在Foo.bar()方法上應(yīng)用一個(gè)非常簡單的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ù)雜程度將隨著你對(duì)同一個(gè)POJO類增加的攔截器的數(shù)量程幾何增長。意識(shí)到了僅使用XML配置文件的限制性,Spring支持在JAVA源代碼中使用Apache Commons metadata來指定事物屬性。在最新的Spring 1.2中,JDK-1.5風(fēng)格的注釋也被支持。為了使用事務(wù)元數(shù)據(jù),你需要為上面例子中的AttributesTransactionAttributeSource 改變一個(gè)transactionAttributeSource bean,并且增加一個(gè)附加的對(duì)元數(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ù)方法時(shí),Spring元數(shù)據(jù)簡化了transactionAttributeSource元素。但是它沒有解決XML配置文件的根本問題:仍然需要冗長的、易錯(cuò)的事務(wù)攔截器,事務(wù)管理器,和事務(wù)屬性。
注射依賴
中間件容器的一個(gè)主要優(yōu)點(diǎn)是它們使得程序開發(fā)人員可以去構(gòu)建松耦合的應(yīng)用程序。服務(wù)使用者僅僅需要知道服務(wù)接口就可以使用服務(wù)。容器把具體的服務(wù)實(shí)現(xiàn)實(shí)例化,然后將它們提供給服務(wù)使用者。這樣,容器可以在可替換的服務(wù)實(shí)現(xiàn)之間進(jìn)行切換,而不改變服務(wù)接口和服務(wù)使用者代碼。
注射依賴模式是實(shí)現(xiàn)松耦合應(yīng)用程序的一個(gè)最好的方式。比起以前的方式,如通過JNDI進(jìn)行查找或回調(diào)容器,注射依賴模式更容易使用,而且更加優(yōu)美。使用注射依賴模式,框架扮演了構(gòu)建服務(wù)的對(duì)象工廠角色,然后根據(jù)運(yùn)行時(shí)的配置,把這些服務(wù)對(duì)象注射到應(yīng)用程序的POJO類中。從程序開發(fā)人員的角度看,作為客戶端使用者的POJO在需要使用服務(wù)對(duì)象前就自動(dòng)的得到了它們。
Spring 和 EJB 3.0都提供了大量的DI模式支持。但是,它們之間也有著根本的不同。Spring支持了通常意義上的但是復(fù)雜的基于XML配置文件的注射依賴API;EJB 3.0支持的注射大多數(shù)通用服務(wù)對(duì)象(如,EJB和容器對(duì)象)和JNDI對(duì)象,它通過簡單的JAVA注解來完成。
EJB 3.0的注射注解相當(dāng)?shù)暮啙嵰子?。@Resource標(biāo)簽注射大多數(shù)的通過服務(wù)對(duì)象和JNDI對(duì)象。下面的例子顯示了如何將JNDI提供的服務(wù)器缺剩數(shù)據(jù)源對(duì)象注射給一個(gè)POJO的一個(gè)字段。DefaultDS是這個(gè)數(shù)據(jù)源的JNDI名字。myDb 變量在第一次被使用前就自動(dòng)被賦予了正確的值。
public class FooDao {
@Resource (name="DefaultDS")
DataSource myDb;
// Use myDb to get JDBC connection to the database
}
在EJB 3.0中,注釋@Resource不僅可以直接注射給屬性變量,它也可以通過setter方法來完成注射。下面的例子將一個(gè)session上下文對(duì)象通過setter方法注射給使用者。應(yīng)用程序不用顯示的調(diào)用setter方法,在任何其他方法被調(diào)用前容器將調(diào)用setter方法完成注射。
@Resource
public void setSessionContext (SessionContext ctx) {
sessionCtx = ctx;
}
對(duì)于更復(fù)雜的服務(wù)對(duì)象,還有一些特殊的注射注解。例如,@EJB 注解被用來注射EJB stubs,@PersistenceContext注解被用來注射實(shí)體管理器對(duì)象,這些對(duì)象負(fù)責(zé)處理EJB 3.0實(shí)體Bean的數(shù)據(jù)訪問操作。 下面的例子給出如何將一個(gè)實(shí)體管理器注射到一個(gè)有狀態(tài)Session Bean中。@PersistenceContext注解的類型屬性描述了被注射的的實(shí)體管理器有一個(gè)擴(kuò)展的事務(wù)容器:它不會(huì)隨著JTA事務(wù)管理器自動(dòng)提交事務(wù),因此它可以應(yīng)用在當(dāng)session中有多次操作的應(yīng)用事務(wù)管理時(shí)。
@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ù)對(duì)象注射到你的POJO類中,你首先需要定義一個(gè)setter方法(或有參數(shù)的構(gòu)造函數(shù)) 。下面的例子演示了 POJO 類中一個(gè)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);
}
}
因此,你可以指定容器如何得到這個(gè)服務(wù),并且在運(yùn)行時(shí)通過配置文件中XML元素的連接關(guān)系把它提供給POJO。下面的例子顯示了連接一個(gè)數(shù)據(jù)源到一個(gè)Hibernate session 工廠、session 工廠到Hibernate模板對(duì)象、模板對(duì)象最后到應(yīng)用程序POJO類,整個(gè)過程的XML配置。
Spring 代碼復(fù)雜性的部分原因是,我們需要手工的去注射Hibernate相關(guān)類,然而,EJB 3.0 實(shí)體管理器被服務(wù)器自動(dòng)管理和配置。但是,這使我們返回到了這樣的討論: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中,包括程序中自定義的。
如果你確實(shí)想在EJB 3.0應(yīng)用中使用Spring的注射依賴功能,你可以將一個(gè)Spring Bean工廠類通過JNDI注射到一個(gè)EJB中。在某些EJB 3.0 應(yīng)用服務(wù)器中,廠商可能會(huì)定義一些非標(biāo)準(zhǔn)的API用來注射任意的POJO類。一個(gè)很好的例子是JBoss MicroContainer,它處理了AOP依賴性,因此它是甚至比Spring 更加通用。
結(jié)論
盡管Spring 和EJB 3.0的目標(biāo)都是提供企業(yè)服務(wù),使得POJO可以松耦合,但是它們實(shí)現(xiàn)的方式非常不同。在兩個(gè)框架中注射依賴模式都有大量的應(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),并且可以同時(shí)與多個(gè)應(yīng)用服務(wù)提供者同時(shí)工作。
感謝
作者感謝Stephen Chambers, Bill Burke, 和Andy Oliver 的有價(jià)值的評(píng)論.
參考
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.
譯者附
翻譯本文不代表譯者本人贊同文中觀點(diǎn),譯者在本文評(píng)論中發(fā)表對(duì)本文的看法和觀點(diǎn)!
另外,轉(zhuǎn)載請轉(zhuǎn)載全文并著明出處,謝謝!