基本的EJB参考,注入和查找
在此博客文章中,我們將研究一些基本示例以了解如何使用EJB API。
基本EJB
EJB本質(zhì)上是帶有一些額外EJB元數(shù)據(jù)的POJO。 可以通過使用EJB批注或通過標(biāo)準(zhǔn)部署描述符來提供將其部署為EJB組件所需的元數(shù)據(jù)。 以下類實(shí)現(xiàn)了一個(gè)非?;镜臒o狀態(tài)會話EJB:
package es.reacts;import javax.ejb.Stateless;@Stateless(name = "UniqueLocalSessionEJB") public class UniqueLocalSessionEJBBean implements UniqueLocalBusinessInterface {public UniqueLocalSessionEJBBean() {}public String sayLocalHello() {return this.getClass().getName() + "::" + "Local hello.";} }正如您可能從我們以前的博客文章中所回顧的那樣, @Stateless批注用于定義無狀態(tài)會話bean。 可選的name元素用于定義會話bean 名稱 。 該元素類似于標(biāo)準(zhǔn)部署描述符的<ejb-name />元素。 此元素默認(rèn)為bean類(UniqueLocalSessionEJBBean在上面的例子中),和上述使用它的示例的非限定名稱重新命名bean來UniqueLocalSessionEJB。
由于我們使用@Stateless批注,因此不再需要在部署描述符中聲明EJB。
在此示例中,我們假設(shè)EJB打包在EJB模塊中,該模塊取決于包含其業(yè)務(wù)接口定義的模塊(如以下部分所述)。
業(yè)務(wù)接口
每個(gè)EJB都實(shí)現(xiàn)一個(gè)或多個(gè)業(yè)務(wù)接口。 業(yè)務(wù)接口可以是本地或遠(yuǎn)程的 。 兩種類型的業(yè)務(wù)接口之間最重要的區(qū)別可以歸納如下:
- 本地業(yè)務(wù)接口對其方法使用按引用傳遞語義,并且方法調(diào)用不能跨越JVM邊界。 本地業(yè)務(wù)接口僅對被調(diào)用方的相同應(yīng)用程序和JVM實(shí)例中的調(diào)用方可用。
- 遠(yuǎn)程業(yè)務(wù)接口對其方法使用按值傳遞語義,并且方法調(diào)用可以跨越JVM邊界。 遠(yuǎn)程業(yè)務(wù)接口可用于被呼叫者應(yīng)用程序之外的呼叫者。
在前面的示例中,業(yè)務(wù)接口UniqueLocalBusinessInterface聲明如下:
package es.reacts;import javax.ejb.Local;@Local public interface UniqueLocalBusinessInterface {String sayLocalHello(); }在EJB v。3.0世界中,業(yè)務(wù)接口只是用@Local或@Remote批注進(jìn)行批注的普通Java接口。
包裝業(yè)務(wù)接口
在此示例中,我們假設(shè)EJB業(yè)務(wù)接口打包在EJB模塊依賴的JAR文件中。 由于EJB客戶端僅依賴EJB業(yè)務(wù)接口,因此,將業(yè)務(wù)接口打包在一個(gè)單獨(dú)的庫中是一個(gè)好習(xí)慣,以簡化接口分配并使它們與實(shí)現(xiàn)分離。
將EJB注入Java Servlet
既然我們已經(jīng)定義了EJB,就可以在Java EE Web模塊中的servlet中使用它了。 假設(shè)在我們的應(yīng)用程序中只有一個(gè)EJB實(shí)現(xiàn)了UniqueLocalBusinessInterface ,我們可以使用空的@EJB注釋將其注入:
package es.reacts;import java.io.IOException; import java.io.PrintWriter;import javax.ejb.EJB;import javax.servlet.*; import javax.servlet.http.*;public class ServletTest1 extends HttpServlet {@EJBUniqueLocalBusinessInterface lc;public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {[...]lc.sayLocalHello();[...]}首先要注意的是,由于僅bean接口就足以識別目標(biāo)EJB,因此應(yīng)用服務(wù)器將EJB注入了EJB。 在這種情況下,@EJB批注的beanInterface元件取它的默認(rèn)值,因?yàn)樵谖覀兘忉屩暗奶?UniqueLocalBusinessInterface:,那是注入字段的類型。 由于應(yīng)用程序中只有一個(gè)EJB可以實(shí)現(xiàn)此業(yè)務(wù)接口,因此servlet的lc字段將注入對此類實(shí)例的引用。
值得指出的第二件事是,由于EJB是無狀態(tài)的 ,因此我們正在將EJB安全地注入到servlet字段中。 由于servlet的默認(rèn)情況下無狀態(tài)的 ,你不應(yīng)該注射狀態(tài)的資源轉(zhuǎn)換成Servlet時(shí)域特性,否則你可能會碰到并發(fā)相關(guān)的問題。 如果需要在Servlet中使用有狀態(tài)EJB,則應(yīng)通過程序化JNDI查找來檢索引用,因?yàn)檫@將確保每次查找操作都返回一個(gè)新實(shí)例。
讓我們部署并運(yùn)行我們的應(yīng)用程序,我們將看到servlet注入了它的目標(biāo)EJB,并且正確執(zhí)行了對其業(yè)務(wù)接口的sayLocalHello()方法的方法調(diào)用。
如果我們想注入對遠(yuǎn)程接口的引用,則客戶端代碼不會受到影響。 如果嘗試將UniqueLocalBusinessInterface從@Local更改為@Remote ,那么您會看到該servlet沒有任何變化,并且可以繼續(xù)正常工作。
如果一個(gè)以上的EJB實(shí)現(xiàn)相同的接口會發(fā)生什么?
假設(shè)我們在此應(yīng)用程序的EJB模塊中添加了另一個(gè)EJB,它實(shí)現(xiàn)了與上一個(gè)相同的接口UniqueLocalBusinessInterface 。 在這種情況下,由于bean接口不再足以確定要注入的目標(biāo)bean,因此將返回一個(gè)錯(cuò)誤。 例如,在WebLogic Application Server中部署這樣的應(yīng)用程序會導(dǎo)致引發(fā)以下錯(cuò)誤:
[08:46:25 PM] Caused by: weblogic.deployment.EnvironmentException: [J2EE:160199]Error resolving ejb-ref 'es.reacts.ServletTest1/lc1' from module 'WebTest0' of application 'EJBTestApp'. The ejb-ref does not have an ejb-link and the JNDI name of the target bean has not been specified. Attempts to automatically link the ejb-ref to its target bean failed because multiple EJBs in the application were found to implement the 'es.reacts.UniqueLocalBusinessInterface' interface. Please specify a qualified ejb-link for this ejb-ref to indicate which EJB is the target of this ejb-ref.注入對特定EJB實(shí)例的引用
為了解決上一節(jié)中出現(xiàn)的問題,我們需要為應(yīng)用程序服務(wù)器提供所需的信息,以標(biāo)識目標(biāo)EJB。 如前一篇文章所述 ,我們可以使用以下兩種方法:
- 我們可以使用@EJB批注的name元素(或部署描述符的相應(yīng)<ejb-ref-name />元素)在應(yīng)用程序的私有名稱空間中聲明EJB引用,然后使用EJB鏈接到目標(biāo)bean。部署描述符。
- 或者,我們使用@EJB批注的beanName元素(或部署描述符的相應(yīng)<ejb-link />元素)直接在我們的代碼中進(jìn)行操作。
將EJB映射到私有命名空間
使用第一種方法,我們將在servlet中獲得以下代碼:
@EJB(name = "ejb/bean-name") UniqueLocalBusinessInterface lc;以及充當(dāng)EJB客戶端的Java EE Web模塊的部署描述符(web.xml)中的以下元素:
<ejb-local-ref><ejb-ref-name>ejb/bean-name</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>es.reacts.UniqueLocalBusinessInterface</local><ejb-link>UniqueLocalSessionEJB</ejb-link> </ejb-local-ref><ejb-link />元素包含我們在示例開頭定義的帶注釋的Bean名稱:
@Stateless(name = "UniqueLocalSessionEJB")在EJB實(shí)現(xiàn)類中。
請注意,在此示例中,我們顯式使用了@EJB name元素,但是我們可以使用其默認(rèn)值來建立鏈接。 name元素的默認(rèn)值為:
[合格的類名稱] / [屬性或字段名稱]在這種情況下,將是:
es.reacts.ServletTest1 / lc
使用默認(rèn)的自動生成的名稱以及使用<ejb-link />進(jìn)行EJB鏈接的缺點(diǎn)是,每次重構(gòu)代碼時(shí),都必須檢查部署描述符。 盡管開發(fā)人員有時(shí)會另外考慮,但Java EE規(guī)范定義了一些其他角色,例如,攻擊者和部署者。 在大型公司環(huán)境中,此類概要文件會覆蓋開發(fā)人員的注釋以“插入”應(yīng)用程序使用的組件并不少見。 注釋覆蓋是標(biāo)準(zhǔn)部署描述符仍然存在的原因之一。 當(dāng)引用是在應(yīng)用程序內(nèi)部或外部的遠(yuǎn)程組件時(shí),尤其如此。 為此,我建議你不要依賴于自動生成的名稱,并使用自定義的有據(jù)可查的名稱代替。
將EJB鏈接到私有命名空間中的引用
第二種方法提供了使用@EJB批注的beanName元素將引用鏈接到其目標(biāo)bean的直接方法。 Servlet代碼將使用以下EJB參考:
@EJB(beanName = "UniqueLocalSessionEJB") UniqueLocalBusinessInterface lc;并且我們不需要部署描述符中的其他信息。
盡管此方法允許開發(fā)人員在不依賴部署描述符的情況下將引用鏈接到EJB,但是上一節(jié)末尾給出的建議仍然有效。 請記住,可以在部署時(shí)覆蓋注釋! 如果事先知道這樣的引用可以覆蓋,則不要將EJB鏈接到引用。 在這種情況下,最好為引用指定一個(gè)名稱,如上一節(jié)所述。
參考: The Gray Blog上的JCG合作伙伴 Gray提供了基本的EJB參考,注入和查找 。
相關(guān)文章 :- EJB 3.0注入和查找簡介
- EJB程序化查找
- 使用Oracle WebLogic對應(yīng)用程序外部的EJB的引用
- EJB 3.1全局JNDI訪問
- GWT EJB3 Maven JBoss 5.1集成教程
- Java泛型快速教程
- JVM如何處理鎖
翻譯自: https://www.javacodegeeks.com/2011/08/basic-ejb-references-injection-and.html
總結(jié)
以上是生活随笔為你收集整理的基本的EJB参考,注入和查找的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特斯拉车型大降22万元 大量中国车主怒了
- 下一篇: Apache CXF负载平衡和故障转移