zoukankan      html  css  js  c++  java
  • ejb2.0用本地引用提高EJB访问效率

    用本地引用提高EJB访问效率

       EJB 1.0和1.1规范只定义了一种在EJB组件中引用另一组件的方法,即通过Bean的远程接口。如果两个Bean都在同一个容器之内,则这种网络开销是不必要的。为解决这个问题,EJB 2.0规范定义了一种新的EJB引用类型,即本地引用。

    一、两种引用类型

       为了从其他EJB组件访问某个Bean,容器提供了一种特殊的机制。这种机制允许一个Bean提供者通过称为EJB引用的“逻辑名字”引用另一个EJB的Home。EJB容器利用应用的部署描述器为EJB构造环境,而这些引用在部署描述器中作为特殊的项目声明。在部署描述器中,部署者把组件代码中要用到的EJB引用绑定到其他被引用EJB的Home。

       如前所述,在EJB 2.0规范出现之前,在一个EJB中引用其他Bean只有一种方法,即通过远程接口,它要求进行跨越网络的远程过程调用。如果某个事务由多个Bean协作完成,通过网络进行多个对象的汇集和释放将是一项相当繁重的工作。

       EJB 2.0规范新增了一种本地接口类型,允许在同一容器之内的Bean直接互相引用,避免了远程接口的网络开销。本地接口是一种标准的Java接口,而不是从RMI继承得到。EJB组件的定义可以包含本地接口或远程接口,或者两者都定义。

       本地引用的指定方式和传统的远程引用一样,即在部署描述器中指定。事实上,本地引用的部署描述元素与远程引用的描述元素完全对应。

    下面的代码片断是一个典型的远程引用:

    Product
    ejb/Product
    Entity
    com.xyz.widgets.ProductHome
    com.xyz.widgets.Product
    ../products/product.jar#Product

    下面的代码片断是同一Bean的本地引用:

    Product
    ejb/Product
    Entity
    com.xyz.widgets.ProductHome
    com.xyz.widgets.Product
    ../products/product.jar#Product

    下表简要说明了各个元素的用途:

    二、创建本地接口,通过本地接口访问EJB

      要把一个现有的远程接口改为本地接口,有三个地方必须修改:部署描述器,Bean的接口,以及对EJB的调用。前面我们介绍了如何通过部署描述器指定一个本地引用,现在我们要把远程接口转换成本地接口,然后修改JNDI查找调用,让它使用新的本地接口。

    ■ Home接口

      指定Home接口时,现在必须导入的是“javax.ejb.EJBLocalHome”,而不是“javax.ejb.EJBHome”。接口的声明也必须改变,让它从“EJBLocalHome”(一个标准Java接口)继承,而不是从“EJBHome”(一个RMI接口)继承。同时,从该接口定义的方法中唯一应该抛出的异常是javax.ejb.CreateException,而java.rmi.RemoteException异常则不再必要。

    ■ 本地接口

      指定本地接口时,现在必须导入“javax.ejb.EJBLocalObject”,而不是“javax.ejb.EJBObject”。接口声明也必须改变,让它从“EJBLocalObject”(一个本地接口)继承,而不是从“EJBObject”(一个RMI接口)继承。

    ■ 执行调用

      创建好接口、设置好部署描述器之后,剩下的工作就是执行JNDI调用,查找对其他EJB的引用。调用Bean的远程接口时,javax.rmi.PortableRemoteObject的“narrow()”方法汇集经过RMI的调用。对于本地引用,这种开销就不再必要,这时只需简单地进行JNDI查找并进行适当的类型定型。下面是一个例子:


    home = (ProductHome) initCtx.lookup("java:comp/env/ejb/Product");


      它不仅提高了效率,而且代码也比用来获取远程接口的代码更直观易懂。

      本地接口使得处于同一容器内的两个EJB组件能够更高效地进行通信。对于实体Bean的应用来说,这种技术尤其有用,因为与客户程序直接访问实体Bean相比,在实践中,通过会话Bean访问实体Bean得到了更广泛的认可。

      如果你准备使用本地引用,请先检查自己的应用服务器平台是否支持它。也许,在EJB 2.0规范获得广泛应用之前,我们还得等待一段时间。


    转自:http://www.bianceng.cn/java/j110.htm

    为什么需要调用ejb的本地接口 ?

      答: 当ejb的服务端和客户端在一个JVM的时候,为了提高jndi查询效率,并且提高方法调用效率,本地调用可以不走TCP/IP ,这样可以明显提高调用的效率!

    ejb2.0 开发本地接口的 步骤:

    朝花夕拾,还是用我的原来ejb2.0的例子,现在需要增加在 原有的基础上增加本地调用的接口

    第一步:

     一共有5个接口,只做远程调用的时候是3个,后面的两个接口是我们做本地调用的时候需要的

    1.远程home接口

    2.远程remote接口

    3.远程实现接口

    4.本地接口

    Java代码  收藏代码
    1. package cn.com.xinli.ejb;  
    2.   
    3. import javax.ejb.EJBLocalObject;  
    4.   
    5. public interface HelloWorldLocal extends EJBLocalObject   
    6. {  
    7.     public String sayHello();  
    8. }  

    5.本地home接口

    Java代码  收藏代码
    1. package cn.com.xinli.ejb;  
    2.   
    3. import javax.ejb.EJBLocalHome;  
    4.   
    5. public interface  HelloWorldLocalHome extends EJBLocalHome   
    6. {   
    7.     HelloWorldLocal create() throws javax.ejb.CreateException;   
    8. }  

    第2步: 编写 ejb-jar.xml ,指定这5个接口的具体实现类

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="gb2312"?>   
    2. <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"   
    3. "http://java.sun.com/dtd/ejb-jar_2_0.dtd">  
    4. <ejb-jar>  
    5.     <description>ejb</description>  
    6.     <display-name>myEJBTest</display-name>  
    7. <enterprise-beans>  
    8.         <session id="ejb_hello">  
    9.             <display-name>helloEJB</display-name>  
    10.             <ejb-name>helloEJB</ejb-name>  
    11.             <home>cn.com.xinli.ejb.HelloWorldHome</home>  
    12.             <remote>  
    13.                 cn.com.xinli.ejb.HelloWorldRemote  
    14.             </remote>  
    15.               
    16.             <local-home>cn.com.xinli.ejb.HelloWorldLocalHome</local-home>  
    17.             <local>cn.com.xinli.ejb.HelloWorldLocal</local>  
    18.               
    19.             <ejb-class>  
    20.                 cn.com.xinli.ejb.HelloWorldBean  
    21.             </ejb-class>  
    22.             <session-type>Stateless</session-type>  
    23.             <transaction-type>Bean</transaction-type>  
    24.         </session>  
    25.           
    26.             <message-driven id="ejb_mdb">  
    27.             <ejb-name>mdb</ejb-name>  
    28.             <ejb-class>cn.com.xinli.ejb.mdb.MDBean</ejb-class>  
    29.             <transaction-type>Bean</transaction-type>  
    30.               
    31.             <acknowledge-mode>Auto-acknowledge</acknowledge-mode>  
    32.             <message-driven-destination>  
    33.             <destination-type>javax.jms.Queue</destination-type>   
    34.             </message-driven-destination>  
    35.         </message-driven>  
    36.     </enterprise-beans>  
    37. </ejb-jar>  

     第3步: 编写 jboss.xml,指定 远程JNDI 和本地JNDI

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="gb2312"?>  
    2. <jboss>  
    3.     <enterprise-beans>  
    4.         <session>  
    5.             <ejb-name>helloEJB</ejb-name>  
    6.             <jndi-name>helloEJB</jndi-name>  
    7.             <local-jndi-name>helloEJBLocal</local-jndi-name>  
    8.         </session>  
    9.     <message-driven>  
    10.         <ejb-name>mdb</ejb-name>      
    11.         <configuration-name>Standard Message Driven Bean</configuration-name>  
    12.         <!-- 消息驱动bean 监听的消息队列的 JNDI  
    13.         <destination-jndi-name>queue/mdb</destination-jndi-name>    
    14.         -->  
    15.       </message-driven>   
    16.     </enterprise-beans>  
    17. </jboss>  

    第4步: 编写 测试页面 ,为了让调用的客户端和ejb 服务器 在一个JVM中,我们需要写一个jsp页面,放在JBOSS的一个war包下,通过JBOSS服务器来访问这个页面,这个页面里面去掉JBOSS服务器上的ejb, 如果你是在 eclpiese 中写的main 方法或者 ejb 的客户端可服务器端就不在一个JVM 中是无法调用Local 接口的

    testejb.jsp

    Html代码  收藏代码
    1. <%@ page contentType="text/html;charset=gb2312"%>  
    2. <%@page import="javax.naming.InitialContext"%>  
    3. <%@page import="java.util.Properties"%>  
    4. <%@page import="javax.naming.Context"%>  
    5. <%@page import="cn.com.xinli.ejb.HelloWorldLocal"%>  
    6. <%@page import="cn.com.xinli.ejb.HelloWorldLocalHome"%>  
    7. <%  
    8. System.out.println("===========================================================");  
    9. Properties props = new Properties();  
    10. props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");  
    11. props.setProperty("java.naming.provider.url", "localhost:1099");  
    12. props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");  
    13. try  
    14. {  
    15.       
    16.        
    17.      Context ctx = new InitialContext();  
    18.   
    19.      HelloWorldLocalHome localHome= (HelloWorldLocalHome) ctx.lookup("local/helloEJB@13889929");   
    20.      HelloWorldLocal local=localHome.create();  
    21.        
    22.      out.println(local.sayHello());  
    23.   
    24.       
    25.       
    26. }  
    27. catch (Exception ex)  
    28. {  
    29.     ex.printStackTrace();  
    30. }  
    31. %>  

    结果图:

  • 相关阅读:
    Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)
    Luogu 1314 【NOIP2011】聪明的质检员 (二分)
    Luogu 1315 【NOIP2011】观光公交 (贪心)
    Luogu 1312 【NOIP2011】玛雅游戏 (搜索)
    Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)
    Luogu 1514 引水入城 (搜索,动态规划)
    UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
    Luogu 1437 [HNOI2004]敲砖块 (动态规划)
    Luogu 1941 【NOIP2014】飞扬的小鸟 (动态规划)
    HDU 1176 免费馅饼 (动态规划)
  • 原文地址:https://www.cnblogs.com/firstdream/p/7846725.html
Copyright © 2011-2022 走看看