网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.基础篇:数组.
.JBOSS-QL中的like、order by的实.
.Java 基本语法(五)——控制流程.
.用javaapi进行sort.
.JBuilder2005单元测试之捆绑多个.
.技术分析之——J2SE 5.0中的泛型.
.学习java&xml心得(2).
.J2ME开发入门专题系列之一:J2ME.
.RMI调用模版.
.用标记区别对象类型会导致误贴标.
.01、《TIJ》为何要读这本书.
.JDBC基础教程之CallableStatement.
.使用.NET Profiler API检查并优化.
.利用jdom实现读取数据库生成XML及.
.Java桌面端程序开发.
.找回丢失的源代码.
.Java Servlet 编程及应用.
.Java图像处理技巧四则.
.用Java增加一个XSLT功能.
.Java的网络编程:用Java实现Web服.

EJB 访问代理设计常用的访问方式

发表日期:2008-1-5



  常规访问方式
  编写过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的方法需要有参数调用。
上一篇:Beans入门必读之经典EJB例子代码 人气:778
下一篇:用JavaBean数据组件集成JSF应用程序与EJB(6) 人气:741
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐