Vaadin应用程序中的EJB查找

自从我实现上一个服务定位器以来已经有很长时间了。 我认为不再需要考虑Java EE CDI (上下文和依赖注入)的成熟度。 我的第一个实现是在基于Struts的Web应用程序中使用EJB。

之后,我开始使用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查找

相关文章 :


翻译自: https://www.javacodegeeks.com/2012/01/ejb-lookup-in-vaadin-application.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值