轻松

记述我学习java的里程

常用链接

统计

积分与排名

友情链接

最新评论

EJB 2.0:“本地”接口和“远程”接口

个新的接口可以使你更有效地访问EJB。学习如何运用它们,以及何时运用它们。
by Rudy Dahbura

当前的EJB 2.0规范有新的接口功能,这在原先的EJB 1.1中是没有的。学习运用这些新的功能,它们可以使你更容易地、更有效地访问EJB。

缺点是什么呢?你将牺牲位置的独立性,但有时侯,这种代价是值得的。了解何时、如何运用新的功能对编写设计良好的EJB应用程序是至关重要的。

EJB 1.1规范给EJB客户端提供了一个remote interface和一个remote home interface与EJB实例交互,得到位置的透明度。以类似的形式,EJB 2.0规范现在给EJB客户端提供了一个local interface和一个local home interface来与共享同一个JVM的EJB实例交互。

EJB remote interface(javax.ejb.EJBObject)和remote home interface(javax.ejb.EJBHome)在本质上是Java RMI接口。远程客户端运用接口和与Java RMI-IIOP兼容的参数与EJBs通讯。参数和方法的结果值在同一个容器中传递,或者跨网络传递到远程容器。

这种编程模式给EJB客户端提供了一种访问EJB组件的方法,就好像这些组件是本地的一样。然后,容器就可以透明地处理网络通讯和执行其它功能。这种方法很适合粗粒度的(coarse-grained)方法调用,其中客户端和EJBs之间的客户端通讯保持到最小限度。

相反,EJB local interface(javax.ejb.EJBLocalObject)和local home interface(javax.ejb.EJBLocalHome)不是Java RMI接口,它们是EJB 2.0的新功能。本地客户端——如其它EJBs,运用相同JVM中传递的参数直接与EJBs通讯。这种技术消除了网络潜在的问题、参数复制的问题以及需要与Java RMI-IIOP兼容的问题。也意味着,EJB客户端可以运用一个更轻量级的编程模式来访问服务。该方法很适合细粒度的(fine-grained)方法调用,因为作为EJB实例的位于同一个JVM中的EJB客户端可以用本地接口来避免不必要的费用。

引进本地客户端产生的另一个显著的变化就是类型的转换。所有的EJB实例在运用前必须转换到它们恰当的接口类型,所以,有时侯,在运用远程客户端时,要保证Java RMI-IIOP的兼容性,你必须在转换EJB实例前运用java.rmi.PortableRemoteObject.narrow()来缩小(narrow)它。

但本地客户端可以直接把EJB实例转换成local home interface类型,如下面的代码片段:
InitialContext initCtx = new 
InitialContext();
   ExampleLocalHome exampleLocalHome = 
(ExampleLocalHome)initCtx.lookup("java:comp/
env/ejb/Example");

从local home创建了EJB实例:
ExampleLocal exampleLocal = 
exampleLocalHome.create();

也许EJB 2.0的最有趣、最容易被忽视的一个方面就是session和entity beans可以同时运用远程和本地接口,这就给了你很大的灵活性。运用两种接口给了潜在的bean客户端最大程度的自由,不管它们是不是在一起的。



<session>和<entity>元素描述了session和entity bean的部署属性。EJB 1.1和EJB 2.0规范定义了两个元素,<home>和<remote>。(以前的规范需要两个元素,但它们在2.0版中是可选的)。它们分别包含EJB remote home interface和remote interface的完全资格类名。

类似地,EJB 2.0规范定义了两个附加的元素,<local-home>和<local>。正如你预料的,它们包含EJB local home interface和local interface的完全资格类名。下面的代码显示了如何运用这些新元素:
<ejb-jar>
   <enterprise-beans>
      <session>
         <ejb-name>...</ejb-name>
         <local-home>...</local-home>
         <local>...</local>
         <ejb-link>...</ejb-link>
         ...
      </session>
   </enterprise-beans>
   <assembly-descriptor>
...
   </assembly-descriptor>
</ejb-jar>

聪明地访问本地客户端的一个实例
本地EJB客户端的概念在如列表1所示的例子中得到了很好地阐明,其中显示了一个无状态session bean,它的local interface和它的local home interface。注意,接口不扩展java.rmi.Remote。

无状态session bean的XML部署描述如下面的代码所示,它也重点强调了<local>和<local-home>元素的运用:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC
   '-//Sun Microsystems, Inc.//DTD Enterprise 
JavaBeans 2.0//EN'
   'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
   <enterprise-beans>
      <session>
         <ejb-name>Example</ejb-name>
         <local-
home>com.acmecorp.ejb.ExampleLocalHome</
local-home>
         <local>com.acmecorp.ejb.ExampleLocal</local>
         <ejb-
class>com.acmecorp.ejb.ExampleBean</
ejb-class>
         <session-
type>Stateless</session-type>
         <transaction-
type>Container</transaction-type>
      </session>
   </enterprise-beans>
   <assembly-descriptor>
      <method-permission>
         <unchecked/>
         <method>
            <ejb-name>Example</ejb-name>
            <method-name>*</method-name>
         </method>
      </method-permission>
      <container-transaction>
         <method>
            <ejb-name>Example</ejb-name>
            <method-name>*</method-name>
         </method>
         <trans-
attribute>NotSupported</trans-attribute>
      </container-transaction>
   </assembly-descriptor>
</ejb-jar>



然后,一个本地的客户端创建并访问一个已经创建的enterprise bean的实例。下面的代码也显示了如何转换一个bean的实例,而不用先缩小它:
<%@ page errorPage="/error.jsp" 
import="javax.naming.*, 
com.acmecorp.ejb.*" 
%>
<%

   InitialContext initCtx = new InitialContext();
   ExampleLocalHome exampleLocalHome = 
(ExampleLocalHome)initCtx.lookup("java:comp/env/
ejb/Example");
   ExampleLocal exampleLocal = 
exampleLocalHome.create();

%>
<html>
<head>
   <title>Default</title>
   <link rel="STYLESHEET" type="text/css" 
href="styles/default.css">
</head>
<body>
   <pre class="code"><%= 
exampleLocal.getMessage() %></pre>
</body>
</html>

在这个例子中,本地客户端是一个JSP页面,因此是一个Web组件。(在有些情况中,当Web组件位于相同的JVM中时,它们访问EJB 2.0本地组件接口。)

最后是Web组件的部署描述:
<web-app>
   <!-- EJB Reference information -->
   <ejb-local-ref>
      <ejb-ref-name>ejb/Example<
/ejb-ref-name>
      <ejb-ref-type>Session<
/ejb-ref-type>
      <local-home>com.acmecorp.ejb.ExampleLocalHome<
/local-home>
      <local>com.acmecorp.ejb.ExampleLocal<
/local>
      <ejb-link>Example</ejb-link>
   </ejb-local-ref>
</web-app>

注意用<ejb-local-ref>元素来声明本地EJB引用。通过<ejb-link>元素得到一个明显的与EJB的链接。它的值必须等于EJB XML描述符中的<ejb-name>元素。

未来会有更大的灵活性?
目前还是公开草案的EJB 2.1规范为访问无状态session beans定义了一个Web services客户端。远程客户端将以一种位置独立的方式与无状态session beans通讯,这种通讯主要运用SOAP 1.1通过HTTP进行基于XML的调用。因为XML、SOAP和HTTP是独立于语言的,所以客户端不需要是Java对象,可以是运行在不同平台上的其它类型的对象。

到那时,EJB 2.0的新功能就会更受Java开发人员的欢迎了,使他们能够创建代码,更有效地运用本地和远程接口。通过运用这些功能,并对你的设计能力进行正确的评估,你就可以创建应用程序,使它们最大限度地运用EJBs。


关于作者:
Rudy Dahbura是位住在洛杉矶的软件顾问。他在洛杉矶的Sierra Systems Group工作,他运用分布式对象技术已经有五年了。他的联系方式是rdahbura@sierrasystems.com

posted on 2005-12-02 17:03 轻松 阅读(4390) 评论(2)  编辑  收藏 所属分类: JAVA转贴

评论

# re: EJB 2.0:“本地”接口和“远程”接口 2006-03-15 15:35 hanry

文章讲到了要点,
我的问题被你化解了
谢谢



hanry
2006.3.15
ihanry@126.com  回复  更多评论   

# re: EJB 2.0:“本地”接口和“远程”接口 2007-07-27 12:44 Jeson

好文章,正是我在找的!  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: