EJB程序化查找

上一篇文章中,我们了解了EJB 引用和EJB 注入 。 尽管EJB注入是一种强大的容器工具,可以简化模块化应用程序的开发,但有时还是需要执行程序化EJB查找。

让我们假设,例如,一组不同的EJB实现了由公共业务接口定义的公共策略 。 根据某种选择算法(例如业务规则 )的结果,选择了不同的策略,因此将在业务流程的范围内执行不同的EJB。 在这种情况下,无法在注入时选择目标EJB,因为注释元素(例如@EJB )是在编译时定义的,而部署描述符是在部署时定义的。 解决此问题的唯一方法是程序化 JNDI 查找

以前的帖子中描述的相同机制将适用。 将使用@EJB批注或Java EE模块部署描述符的相应元素声明EJB引用并将其与应用程序私有名称空间中的名称链接。

在应用程序专用命名空间中查找

在查询代码中使用的名称空间和目标EJB之间建立间接级别的可移植方法是使用应用程序专用名称空间。 这种间接级别在Java EE平台中非常普遍:不仅用于EJB引用,而且用于各种资源引用,例如JDBC数据源,JMS队列,JavaMail会话等。

对于EJB,如我们之前的文章所述,您只需定义一个私有名称,供应用程序的查找和注入代码使用。 这是一个专用于应用程序的名称,是java:comp / env JNDI条目的子元素。 借助@EJB批注和部署描述符,您可以在此名称和目标EJB之间建立链接。 唯一的区别是,应用程序算法将选择适当的EJB并动态查找,而不是依赖容器将引用注入到您的组件中。

正如我们在已经看到部分2这一系列中,@EJB注释可以在类型,方法和字段级用于声明对EJB的引用,并且,任选地,而不需要写任何的将其链接到目标豆部署描述符代码。

如果是动态编程JNDI查找,则可以注释一个类(例如Servlet)来建立对EJB的引用,而不是将字段(或属性)注释为注入目标。 在下面的示例中,我们将看到如何同时使用@EJB注释和部署描述符。

声明对EJB的引用

在之前的文章中使用的测试servlet中,我们可以在类级别使用@EJB批注以私有名称ejb / ejbLocalRef声明对EJB的引用:

@EJB(name = "ejb/ejbLocalRef",
     beanInterface = es.reacts.SessionTest0Local.class,
     beanName = "EJBServer1.jar#SessionTest1")
public class ServletTest1 extends HttpServlet {
  [...]
}

上一个示例中的注释在功能上等效于以下部署描述符(在本例中为web.xml文件)片段:

<ejb-local-ref>
  <ejb-ref-name>ejb/ejbLocalRef</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <local>es.reacts.SessionTest0Local</local>
  <ejb-link>EJBServer1.jar#SessionTest1</ejb-link>
</ejb-local-ref>

此示例中的@EJB语义与上一篇文章中的示例之间的最重要区别是,在这种情况下,我们提供了建立引用和到目标EJB的链接所需的所有信息,而无需注入甚至不依赖有关来自注入目标的信息(例如beanInterface )。

尽管注释是在类级别应用的,但实际上等效于添加相应的部署描述符元素,因此, 声明的引用将在整个Java EE模块中可用 。 在这种情况下,您的Java EE Web模块中的任何其他servlet都可以注入或查找由ejb / ejbLocalRef名称引用的相同EJB:

@EJB(name = "ejb/ejbLocalRef")
SessionTest0Local lc4;

由于引用声明包含解析目标EJB所需的所有信息,因此此处不需要额外的“管道”。

EJB程序化查找

由于已经声明并链接了引用,因此我们的代码现在可以进行JNDI查找,并检索对目标EJB所需业务接口的引用。 JNDI查找代码是我们习惯的良好的ole查找代码(稍有不同,我们将在后面指出):

InitialContext ctx = new InitialContext();
Object obj = ctx.lookup("java:comp/env/ejb/ejbLocalRef");
if (obj instanceof SessionTest0Local) {
  SessionTest0Local lc = (SessionTest0Local) obj;
  [...]
}

(* 请注意,前面的片段已删除了所需的异常处理代码 。)

EJB 3.0的一个好消息是,您不需要像EJB v。2.1规范所要求的那样使用PortableRemoteObject.narrow()方法来缩小引用的范围。 在示例代码中,我们可以使用instanceof运算符直接测试引用,并使用Java本机强制转换设置SessionTest0Local引用。

查找本地和远程业务接口之间绝对没有区别。 仅在依赖部署描述符的情况下,才会根据EJB业务接口类型使用<ejb-ref>或<ejb-local-ref>执行EJB引用的声明和链接。 就您的应用程序而言,查找代码将相同。

模式

在不使用EJB注入而是依靠查找的情况下,使用注释或部署描述符声明和链接EJB引用既有优点也有缺点。

注释的优点是,它们比相应的部署描述符元素更易于编写和使用。 而且,就我的经验而言,IDE对代码自动完成的支持可能比某些“晦涩”的部署描述符编辑器更好(最好是例外)(Oracle JDeveloper和NetBeans等例外)。

部署描述符的优点是它可以集中资源引用声明。 如果在您的Java EE模块的整个代码中都使用相同的EJB引用,并且不将其限制在单个类中,那么最好的选择是使用部署描述符声明和链接EJB(和其他资源)引用,并避免使用注释。 这是必须谨慎选择的设计选择。 在需要查找的用例中,很有可能在应用程序组装部署阶段执行EJB链接。 最好还是在中央存储库中对引用进行充分记录和声明,而不是在整个代码中散布@EJB注释,这样部署人员的工作可能会大大减轻。

参考: The Gray Blog上我们JCG合作伙伴 Gray的 EJB程序化查找

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/08/ejb-programmatic-lookup.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值