帝国软件
  设为首页 加入收藏 关于我们
 
解密帝国网站管理系统
栏 目:
 
您的位置:首页 > 技术文档 > JAVA编程 >
EJB访问代理设计
作者:未知 发布时间:2005-03-12 来源:JSP天空网
常规访问方式

  编写过EJB(Enterprise Java Bean)访问程序的朋友都知道,通过客户端或服务端的程序访问EJB(即获得一个EJB Remote或Local对象)通常要经历以下几个步骤:

  (1)创建一个初始化上下文(initial context);

  (2)通过JNDI查找对应的EJB上下文对象;

  (3)通过获得的上下文对象获得一个Home或者LocalHome对象(获得Home对象通过PortableRemoteObject对象的narrow方法,获得LocalHome对象通过强制类型转换);

  (4)最后通过Home或LocalHome的create方法创建一个Remote或Local对象,通过Remote或Local对象真正使用服务器的EJB提供的方法。

代理类设计


  如果我们能够把以上4个步骤封装在一个类(本文叫EJBAgent)的方法(getRemote和getLocal)内就可以使得获得一个Remote或Local对象只需要提供一个JNDI的名称,避免了重复拷贝以上4个步骤的代码。写过EJB访问代码的程序员都知道,1~3步是很容易封装起来的,以下是典型的代码:

/*1.*/ InitialContext context = new InitialContext (properties);

/*2.*/ Object home = context.lookup(JNDIName);

/*3.*/ EJBHome ejbHome =

(EJBHome) PortableRemoteObject.narrow (home, EJBHome.class);

  第一步获得一个Context,主要是获得应用服务器的环境参数,我们可以把存放环境变量的pertieserties对象作为参数,第二步是查找EJB上下文对象,可以把JNDIName作为参数,第三步获得Home对象,我们可以统一获得Home对象的父类:EJBHome,应用程序在具体根据实际使用的Home接口作类型转换。

  第四步通过create方法创建一个Remote或Local对象封装就有一定困难了,因为我们在第三步获得的是一个EJBHome的接口,而我们知道,EJBHome接口本身不提供create方法(对EntityBean有可能是findByPrimaryKey的方法),而是由具体的应用程序的Home接口定义的,所以如果我们直接在代码体写ejbHome.create(),会产生一个编译错误,提示方法create没找到。要使程序能够执行create方法,一种办法是把ejbHome强制类型转换成应用程序定义的EJBHome类型,即(EJBHome)换成(EJBExampleHome),其中EJBExampleHome是应用程序定义的EJBHome接口,但这样必须在代码体中写入应用程序定义的EJBHome类名称,达不到通用处理的目的。但我们知道,通过PortableRemoteObject.narrow出来的EJBHome其实是应用程序的定义的Home接口,即虽然我们使用(EJBHome)作类型转换,但ejbHome实际指向的对象是EJBExampleHome,其中就定义create方法,我们可以采用动态调用的方式调用create方法,从而避免在编译时产生错误。java.lang.reflect包提供了通过方法名称动态调用方法的Method类。以下代码是上述思想的实现:

/*3.*/ EJBHome ejbHome =

(EJBHome) PortableRemoteObject.narrow (home, EJBHome.class);

/*4.*/ Class ejbHomeClass = ejbHome.getClass();

/*5.*/ Method method = ejbHomeClass.getDeclaredMethod("create",null);

/*6.*/ Object remoteObject = method.invoke(ejbHome,null);

  其中第4步是获得ejbHome的Class,可能有部分朋友以为是获得EJBHome的类,其实获得的Class是应用程序定义的EJBHome接口:应用程序定义的类EJBExampleHome。有兴趣的读者可以通过getName()方法获得实际Class名称作判断。第五步通过获得的Class获得一个定义的create方法。getDeclaredMethod有两个参数,第一个是方法的名称,是String类型,第二个是参数类型,是Class数组。由于create方法是没有参数,所以getDeclaredMethod第二个参数是null。需要注意的是getDeclaredMethod是动态执行的,所以第一参数:方法名称如果写错,编译时是不会产生错误的,在实际执行时才会报错,抛出“没有该方法”的异常:NoSuchMethodException。第6步通过动态调用create方法创建Remote对象。与getDeclaredMethod方法对应,Method的invoke方法也有两个参数,第一个参数是定义执行方法的对象,Object类型,第二个参数是调用方法的参数,是Object数组,因为create方法没有参数,所以第二个参数设置为null。

例子介绍


  以下以WebLogic6.1作应用服务器为例子说明EJBAgent的使用方法。我们建立一个叫EJBExample的SessionBean,其Home接口为EJBExampleHome,Remote对象为EJBExampleRemote,其JNDI名称为EJBExample。通过以下代码体获得一个EJBExampleRemote的对象:

Properties properties = new Properties();

properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");

properties.put(Context.PROVIDER_URL,"t3://localhost:7001";);

EJBAgent agnet = new EJBAgent(properties);

EJBExampleRemote remote = (EJBExampleRemote)agent.getRemote("EJBExample");

  通过获得的remote对象就可以操作服务器端EJBExample的方法。我们可以看到,整个过程只需要两个参数:应用服务器环境properties和对应的EJB JNDI名称,强制类型转换也只需要在获得Remote对象时才使用到。而且通常一个应用程序是连接到一个应用服务器上,所以properties参数通常只需要设置一次,这样可以只产生一个EJBAgent实例供多个客户端程序使用,既减少了代码量,也提高了重用性。如果我们想获得的是一个Local对象,则可以不必构造一个properties对象作为参数,为获得Local对象的程序通常是运行在应用服务器端的SessionBean,直接使用new InitialContext()则可以获得应用服务器的环境参数。所以EJBAgent提供了有参和无参两个构造方法,分别供Client端和Application Server端的应用程序使用。具体的实现请看EJBAgnet.java。下面就EJBAgnet的部分关键代码作说明:

  (2)以静态static的方式定义EJBAgent使用的context对象:避免EJB访问程序多次重新获得Context。在局域网的环境中,从clinet获得一个Context的时间在1~3秒范围内,笔者在局域网用WebLogic6.1作应用服务器作过时间比较,获得一个Context平均花1.3秒,而获得一个Home和Remote对象只分别花17和36毫秒,所以把获得的Context用静态方式缓存以供调用时使用大大减少了应用程序访问EJB的时间;

  (2)针对Entity Bean的访问增加了getRemoteByKey和getLocalByKey的方法,可以通过JNDI Name和Primary Key的对象获得一个EntityBean Remote或Local对象,同样通过动态调用的方式实现。与create方法创建EJB的区别是findByPrimaryKey的方法需要有参数调用。
  
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
无相关信息

   栏目导行
  PHP编程
  ASP编程
  ASP.NET编程
  JAVA编程
   站点最新
·致合作伙伴的欢迎信
·媒体报道
·帝国软件合作伙伴计划协议
·放眼未来 帝国近期将有重大举措!
·PHPWind6.3.2版通行证发布
·帝国备份王2008版正式发布
·帝国备份王2008版发布
·phpcms2007转帝国CMS5.0程序发布
·dedecms5.1转帝国CMS5.0程序发布
·帝国网站管理系统V5.0商业购买说明
   类别最新
·谈谈JDBC
·JDBC专题介绍
·JDBC接口技术
·利用weblogic的POOL(连接池)连接
·Jsp中调用Oracle存储过程的小例子
·JSP数据库操作例程
·JSP数据库连接大全
·用连接池提高Servlet访问数据库的效
·一种简单JDBC连接池的实现
·数据库连接池Java实现小结
 
关于帝国 | 广告服务 | 联系我们 | 程序开发 | 网站地图 | 留言板 帝国网站管理系统