之后,我開始使用JSF,它只需要帶有@EJB或@Resource的帶注釋的屬性即可與業務層進行通信。 到目前為止,在他們讓我評估Vaadin作為用于商業應用程序的前端技術之前,這一直是一個很棒的經驗。
在深入探討之前,我已經閱讀了Vaadin Wiki上發布的文章“ Adding JPA to the Address Book Demo ”,其中介紹了如何從Vaadin的類中調用EJB,以檢索和持久化業務層的數據。 EJB使用JPA來獲取數據并將其放入數據庫中。 他們建議從自定義servlet調用EJB,根據Java EE規范,該自定義servlet具有使用CDI進行EJB調用的能力。
如果要調用1個或3個EJB,這似乎是一個合適的解決方案,但是當要處理大約40個EJB時,在Servlet中該怎么辦? 如何將所有這些引用傳遞給Vaadin的應用程序類? 此類的接口可能會發瘋! 這就是為什么我認為使用JNDI進行查找是可取的。
以下代碼是我在概念證明(PoC)中使用的服務定位器。
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;public class MyServiceLocator {private Context initialContext;private Map cache;private static ClientServiceLocator ourInstance = new ClientServiceLocator();public static ClientServiceLocator getInstance() {return ourInstance;}private ClientServiceLocator() {try {this.initialContext = new InitialContext();this.cache = Collections.synchronizedMap(new HashMap());}catch(NamingException ne) { System.err.printf("Error in CTX looking up %s because of %s while %s",ne.getRemainingName(),ne.getCause(),ne.getExplanation());}}public Object lookupEjb(String ejbName) {if(this.cache.containsKey(ejbName)) {return this.cache.get(ejbName);}else {try {Object ejbRef = initialContext.lookup("java:comp/env/"+ ejbName);this.cache.put(ejbName, ejbRef);return ejbRef;} catch (NamingException ne) {throw new RuntimeException(ne);} catch (Exception e) {throw new RuntimeException(e);}}}
}
MyServiceLocator類遵循Singleton設計模式,請確保只有一個對象實例可以滿足來自Web應用程序的所有請求。 唯一實例是在類的初始化過程中創建的,并且由于構造函數是私有的,因此該類不能被另一個類實例化,只能通過方法getInstance ()獲得。 構造函數初始化上下文,并創建一個同步映射,其中存儲了所有已創建的引用。 方法lookupEjb ( 字符串ejbName )查找名稱在本地JNDI上下文中可用的EJB。 此方法僅適用于在web.xml文件中聲明了其引用的EJB,如下所示。
<web-app version="2.5"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><display-name>Information Systems</display-name>...<ejb-local-ref><ejb-ref-name>InformationSystemBean</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>example.business.InformationSystemBeanLocal</local><ejb-link>eac-architecture-ejb.jar#InformationSystemBean</ejb-link></ejb-local-ref>
</web-app>
標記<ejb-local-ref>用于聲明對本地EJB的引用。 上面的示例僅映射一個EJB。 因此,您必須對要映射的每個EJB重復此操作。 有關此標簽的詳細信息,請參見此處 。 聲明之后,我們可以使用以下代碼在應用程序的任何部分中獲取EJB的實例:
private InformationSystemLocal informationSystemBsn = (InformationSystemLocal)MyServiceLocator.getInstance().lookupEjb("InformationSystemBean");
變量是使用EJB本地接口(即InformationSystemLocal )鍵入的。 服務定位器返回名為InformationSystemBean的EJB實例,默認情況下是EJB的實現類。 請注意,當我們使用CDI時,上面的代碼都不是必需的。 AjudaBsn的調用就像這樣:
@EJB
private InformationSystemLocal informationSystemBsn;
CDI很好且優雅,但不能廣泛應用。 今天實現它的方式是Java EE規范的主要弱點。 也許有很強的理由為什么EJB的注釋不能在每個Java類中都起作用。 我根本看不到這個錯誤的原因,因為Spring自從很久以前就已經使用方面取向解決了這個問題。
參考: Hildeberto博客上的 JCG合作伙伴 Hildeberto Mendonca提供的Vaadin應用程序中的EJB查找
相關文章 :
- JBoss AS 7 EJB3池配置
- Java EE6 CDI,命名組件和限定符
- EJB程序化查找
- EJB 3.0注入和查找簡介
- 什么是CDI,它與@EJB和Spring有什么關系?
翻譯自: https://www.javacodegeeks.com/2012/01/ejb-lookup-in-vaadin-application.html