分享
 
 
 

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

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

常规访问方式

编写过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的方法需要有参数调用。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有