EJB 工厂和数据类

EJB 工厂和数据类访问 bean 代表在工作台中使用的新访问 bean 设计。

本主题包括下列部分:

在适当的地方将 EJB 工厂和数据类与仍在使用原始设计的 Java™ bean 包装器和复制助手进行了比较。

使用 EJB 工厂来实例化企业 bean

为说明如何使用 EJB 工厂来实例化企业 bean,假定您具有一个称为 MyEJB 的现有实体 bean。当创建了 MyEJBAccessBean 时,就将缺省构造函数映射至 findByPrimaryKey(MyEJBKey)。MyEJBKey 将单个“字符串”字段命名为字段 lastName。

在原始访问 bean 设计中,可按以下方式来使用访问 bean 实例:
   MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to
          findByPrimaryKey(MyEJBKey);
         ab.setInitKey_lastName = "stokes";
          int i = ab.getAnInt(); // <- findByPrimaryKey(MyEJBKey) occurs here
     ...
在新的访问 bean 设计中,可以完全相同的方式来编写代码:
     MyEJBFactory factory = new MyEJBFactory();
     MyEJB myEjb = factory.findByPrimaryKey(new MyEJBKey("stokes"));
       int i = myEjb.getAnInt();
     ...
或者,可以按以下方式来编写代码:
     MyEJBFactory factory = new MyEJBFactory();
          MyEJBKey key = new MyEJBKey("stokes");
          MyEJB myEjb = factory.findByPrimaryKey(key);
       int i = myEjb.getAnInt();
    ...
在原始设计中,如果想要使用除了映射至无参数构造函数的方法之外的 home 接口方法,则可以编写下列代码:
   MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create occurs here
          ab.setAnInt(5);
     ...
而在新设计中应编写以下代码:
     MyEJBFactory factory = new MyEJBFactory();
          MyEJB myEjb = factory.create("stokes");
          myEjb.setAnInt(5);
     ...
或者,可以按如下所示来编写它的代码:
   MyEJB myEjb = new MyEJBFactory.create("stokes");
          myEjb.setAnInt(5);
     ...
如果 MyAccessBean 将 create(String) 用作缺省 home 接口方法,在原始设计中,可以按以下方式来构造访问 bean 实例:
   MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to create(String);
          ab.setInit_argKey = "stokes";
          int i = ab.getAnInt(); // <- create(String) occurs here
     ...
在新设计中,应使用以下代码:
     MyEJBFactory factory = new MyEJBFactory();
          MyEJB myEjb = factory.create("stokes");
       int i = myEjb.getAnInt();
     ...

使用 EJB 工厂来设置上下文工厂和提供程序 URL

假定您需要引用当前“系统”属性设置引用的命名上下文之外的命名上下文。 如果已经将无参数构造函数映射至 findByPrimaryKey(),则在原始设计中,将使用以下代码:
   MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to
      findByPrimaryKey();
      ab.setInit_NameServiceTypeName("com.ibm...CNInitialContextFactory");
      ab.setInit_NameServiceURLName("IIOP://9.21.35.100:900");
        ab.setInitKey_lastName = "stokes";
        int i = ab.getAnInt(); // <- findByPrimaryKey() occurs here
    ...
在新设计中,可以几乎完全相同的方式来编写同样的代码:
    MyEJBFactory factory = new MyEJBFactory();
    factory.setInitialContextFactoryName("com.ibm...CNInitialContextFactory");
       factory.setInitialNameServiceProviderURL("IIOP://9.21.35.100:900");
    MyEJB myEjb = factory.findByPrimaryKey(new MyEJBKey("stokes"));
    int i = myEjb.getAnInt();
  ...
然而,如果想要使用不是映射至缺省构造函数(在此例中为 findByPrimaryKey)的 home 接口方法,在原始设计中,将不能使用下列代码:
       MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create() occurs here
    // The following two lines have no effect, because the home is already acquired
    ab.setInit_NameServiceTypeName("com.ibm...CNInitialContextFactory");
    ab.setInit_NameServiceURLName("IIOP://9.21.35.100:900");
       int i = ab.getAnInt();
  ...
而将需要使用以下代码:
   //The following two lines call static setters on the AbstractAccessBean class
          MyEJBAccessBean.setInit_GlobalNameServiceTypeName("com.ibm...CNInitialContextFactory");
          MyEJBAccessBean.setInit_GlobalNameServiceURLName("IIOP://9.21.35.100:900");
          MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create() occurs here
          int i = ab.getAnInt();
     ...

然而,对于线程来说,此代码不是很安全。如果线程刚好在其构造函数调用之前中断,而另一个线程将这些全局值设置为别的值,则访问 bean 将不引用您设置的名称服务。在新设计中,应使用以下代码:

     MyEJBFactory factory = new MyEJBFactory();
          factory.setInitialContextFactoryName("com.ibm...WsnInitialContextFactory");
          factory.setInitialNameServiceProviderURL("IIOP://9.21.35.100:900");
          MyEJB myEjb = factory.create("stokes");
       int i = myEjb.getAnInt();
     ...

使用数据类对进行高速缓存操作

如果您正在使用复制助手访问 bean 来设置若干属性,则可以使用以下代码:
   MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- maps to
          find(String)
          ab.setAnInt(5);
          ab.setAString("xxx");
     ...
      ab.commitCopyHelper();

在新设计中,可高速缓存属性将存储在单独的对象中;例如,MyEJBData。现在,将按如下所示来为复制助手编写代码:

   MyEJBData data = new MyEJBData();
          data.setAnInt(5);
          data.setAString("xxx");
     ...
     MyEJB myEjb = new MyEJBFactory().find("stokes");
      myEjb.setMyEJBData(data);

如果您正在使用复制助手访问 bean 来获取若干属性,则可以编写类似以下代码的代码:

   MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- maps to
          find(String)
          int i = ab.getAnInt();
          String s = ab.getAString();
     ...

在新设计中,将按如下所示来编写代码:

   MyEJB myEjb = new MyEJBFactory().find("stokes");
          MyEJBData data = myEjb.getMyEJBData();
          int i = data.getAnInt();
          String s = data.getAString();
     ...

异常处理

在原始设计中,如果您使用映射至 findByPrimaryKey 的缺省构造函数创建了 MyEJBAccessBean,则客户机代码可能类似于以下片段:
   MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to
          findByPrimaryKey(MyEJBKey);
         ab.setInitKey_lastName = "stokes";
     try {
              int i = ab.getAnInt(); // <- findByPrimaryKey(MyEJBKey) occurs here
         ...
          } catch (NamingException nameExc) {
         ...
          } catch (FinderException finderExc) {
         ...
          } catch (CreateException createExc) {
         ...
          } catch (RemoteException remoteExc) {
         ...
     } // endtry

在新设计中,将按如下所示来编写同样的代码:

     MyEJBFactory factory = new MyEJBFactory();
     try {
                  MyEJB myEjb = factory.findByPrimaryKey(new
          MyEJBKey("stokes"));
           int i = myEjb.getAnInt();
         ...
          } catch (FinderException finderExc) {
         ...
          } catch (RemoteException remoteExc) {
         ...
     } // endtry

反馈