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. %>  

    结果图:

  • 相关阅读:
    C++ STL 一般总结(转载)
    Python高级语法总结
    Adaboost 算法的原理与推导——转载及修改完善
    简化版SMO算法标注
    【转载】机器学习算法基础概念学习总结
    C++中添加配置文件读写方法
    Python中scatter()函数--转载
    python 之 strip()--(转载)
    zabbix邮件报警脚本(Python)
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/firstdream/p/7846725.html
Copyright © 2011-2022 走看看