其实应用服务器就是用这样的机制处理多client访问ejb的。你不用自己创建连接池。

解决方案 »

  1.   

    lookup和home.create很好时间如果安全允许的话,你可以试试下面的方法MyEJBHome home = (MyEJBHome)ctx.lookup("MyEJB");
    HomeHandle myHomeHandle = home.getHomeHandle();以后要用home的时候就
    MyEJBHome home = myHomeHandle.getEJBHome();
    这样可以减少jndi查找的时间消耗这个Handle应该是可以从网络中传输的,因为可以序列化,所以可以在多个机子上面共用这个HandleEJBObject也有Handle,不过保存这个Handle的情况好象很少见
      

  2.   

    SAsura:你是说在某一个客户端创建了一个Handle,在别的客户端也可以调用码????
    关于lookup是比较费时间,但是客户端只要连接一次就可以了,那样只要你不关闭它就可以一直调用你所有的EJB,我想也不是不可以接受吧。
      

  3.   

    我觉得Handle类的内部实现机制应该是1)当前Home接口有效,返回当前Home接口
    2)当前Home接口无效,重新Lookup
    所以通过序列化传到别的客户端也应该可以使用因为Home接口本身是不能被序列化的,所以你无法将它通过网络传送出去,而且我认为J2EE平台,例如:jboss,weblogic,对于Home接口是应该有缓冲处理的,具体的实现应该就是通过HomeHandle,不然这个借口是干嘛用的,弄着好玩?我认为相对于保存Home接口,保存HomeHandle应该是一个更为合理的方法,同理EJBObject也有Handle接口,实现机制估计差不多,对于有状态的SessionBean,传递整个SessionBean应该是不妥当的,应该传递Handle吧不过上面都是我的猜测而已,呵呵,别打我,我这里条件有限,无法测试,等我去找jboss的源码看看具体的实现在说
      

  4.   

    我刚才去看了jboss2.4.3的源代码,我的理解有偏差,不管创建HomeHandle的Home接口是否有效,HomeHandle都会去重新lookup以保证返回的Home接口的有效性,看来HomeHandle只是提供了一种传递Home接口的办法,并没有起到缓冲的作用,而对于stateless和stateful的Handle,jboss也有不同的处理,stateless会去重新lookup,重新create,而stateful则会去用rmi接口调用容器的方法获得原来的SessionBean,保证调用的正确,看来安全与速度比起来jboss还是选择了安全
      

  5.   


    建议参看一下《J2EE核心模式》一书中的 服务定位器。
      

  6.   

    再贴一段我以前的代码,就是服务定位器的实现。
    public class ServiceLocator {  private Map ejbHomes;
      private static ServiceLocator aLocatorSingleton;
      Context ctx;  /**
       * private constructor.
       */
      private ServiceLocator() throws NamingException {
        try {
          ctx = new InitialContext();
          this.ejbHomes = Collections.synchronizedMap(new HashMap());
        }
        catch(Exception e){}
      }
      /**
       * »ñÈ¡Ò»¸öʵÀý(µ¥Ìå)
       * */
      public static ServiceLocator getInstance() throws PRPLocatorException {
        try {
          if ( ServiceLocator.aLocatorSingleton == null ) {
            ServiceLocator.aLocatorSingleton = new ServiceLocator();
          }
        }
        catch (NamingException e) {
          throw new PRPLocatorException(e);
        }    return ServiceLocator.aLocatorSingleton;
      }
      /**
       * ²éÕÒHome½Ó¿Ú£¬Èç¹ûÓÃhomeµÄÈ«°üÃû×÷ΪjndiÃû¡£
       * @param homeClass Òª²éÕÒµÄÀà
       * */
      public EJBHome lookupHome(Class homeClass)  throws PRPLocatorException {
        EJBHome anEJBHome;
        anEJBHome = (EJBHome) this.ejbHomes.get(homeClass);
        try {
          if(anEJBHome == null) {
            anEJBHome = (EJBHome) PortableRemoteObject.narrow(ctx.lookup(homeClass.getName()), homeClass);
            this.ejbHomes.put(homeClass, anEJBHome);
          }
        }
        catch (ClassCastException e) {
             throw new PRPLocatorException(e);
        }
        catch (NamingException e) {
             throw new PRPLocatorException(e);
        }
        return anEJBHome;
      }  /**
       * ²éÕÒHome½Ó¿Ú£¬ÌṩjndiÃû¡£
       * @param homeClass Òª²éÕÒµÄÀà
       * @param jndiName ´ËHomeµÄjndiÃû
       * */
      public EJBHome lookupHome(Class homeClass, String jndiName) throws PRPLocatorException {    EJBHome anEJBHome;
        anEJBHome = (EJBHome) this.ejbHomes.get(homeClass);    try {
          if(anEJBHome == null) {
             anEJBHome = (EJBHome) PortableRemoteObject.narrow( ctx.lookup (jndiName), homeClass);
             this.ejbHomes.put(homeClass, anEJBHome);
           }
        }
        catch (ClassCastException e) {
          throw new PRPLocatorException(e);
        }
        catch (NamingException e) {
          throw new PRPLocatorException(e);
        }    return anEJBHome;
      }  /**
       * ¸ù¾Ý¸ø³öµÄjndiÃû²éÕÒÊý¾ÝÔ´
       * @param jndiÃû
       * @return Êý¾ÝÔ´
       * */
      public DataSource lookupDataSource(String jndiName) throws PRPLocatorException {
        try{
          DataSource ds = (DataSource)ctx.lookup("java:/"+jndiName);
          return ds;
        }
        catch(Exception ex){
          throw new PRPLocatorException(ex);
        }
      }  /**
       * ¸ù¾Ý¸ø³öµÄ¶ÔÏóÐòÁкŻñÈ¡±£´æµÄEJB¶ÔÏó
       * @param id ¶ÔÏóÐòÁкÅ×Ö´®
       * @return È¡³öµÄEJB¶ÔÏó
       * */
      public static EJBObject getService(String id) throws PRPLocatorException {
        if( id==null ) throw new PRPLocatorException("Null serialized string.");
        try{
          byte[] bytes = new String(id).getBytes();
          ObjectInputStream os = new ObjectInputStream(new ByteArrayInputStream(bytes));
          javax.ejb.Handle handle = (javax.ejb.Handle)os.readObject();
          return handle.getEJBObject();
        }
        catch(Exception e){
          throw new PRPLocatorException(e);
        }
      }
      /**
       * ±£´æEJB¶ÔÏó²¢»ñÈ¡±£´æµÄÐòÁкÅ
       * @session Òª±£´æµÄEJB¶ÔÏó
       * @return ±£´æ¶ÔÏóÐòÁÐ×Ö´®
       * */
      public static String getId(EJBObject session) throws PRPLocatorException {
        try{
          javax.ejb.Handle handle = session.getHandle();
          ByteArrayOutputStream fo = new ByteArrayOutputStream();
          ObjectOutputStream so = new ObjectOutputStream(fo);
          so.writeObject(handle);
          so.flush();
          so.close();
          return new String(fo.toByteArray());
        }
        catch(Exception e){
          throw new PRPLocatorException(e);
        }
      }}
      

  7.   

    使用ejb,效率是一个很大的问题,所有就有了ejb的设计模式。
    ejb的设计模式(楼上的《J2EE核心模式》)中就讲了有关ejb的几种模式。
    ServiceLocator模式(楼上的就是讲的ServiceLocator模式)。
    Session Facade模式
    Page-by-Page Iterator模式
    Value Object模式
    CMR模式
    Local模式
    DAO模式
    Fast-Lane-Reader模式
    等等。以上模式在ejb设计模式中讲得很好。具体是怎么样的,请参考ejb设计模式(J2EE核心模式)。
    希望和懂ejb设计模式的网友谈谈。
      

  8.   

    to sharetop(老大不小)我就是看了这个模式以后才有以上的问题的
    你贴出的代码我也看过,但我不是很理解我是奇怪,为什么不可以用类似数据库连接池这样的技术
    来建立一个HOME的池呢?
      

  9.   

    其实最花时间的是lookup过程,所以要解决的就是避免重复这个操作。这样就够了。
      

  10.   

    楼上有位兄弟说过了啊。服务器端已经为你维护着一个池了,为什么非要用池呢?就象你如果用了datasource,它其实也是server为你维护的一个池,你只需从它那里getConnection即可,是不是你还会把取出的多个connection再放入一个池里呢?在使用EJB的时候,我们很大程序上依赖于服务器为我们实现的一些性能。我想你说的池,主要是在用jsp/servlet时那个池的影响吧,那时我也是从网上找了一个池的实现代码,而没有用server提供的池,主要是为了在tomcat下跑。但是如果你想用EJB,多数是不会自己再去用这个池的实现了,肯定是用server提供的datasource,对吧?
      

  11.   

    谢谢sharetop(老大不小)这么不厌其烦给我解释
    最后再请教一下
    这个EJBHOMEFACTORY模式我不是很理解
    能简要的解释一下吗?谢谢!