用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发
|
接上篇: 14 、下面我们编写一个 SessionBean 来测试我们的 CMP 实体 Bean 。我们的通常做法是用 SessionBean 来封装 CMP 实体 Bean ,然后再在 JavaBean 和 Servlets 及 jsp 中引用该 SessionBean 。这样使得 CMP 实体 Bean 对用户来说是不可见的。创建 SessionBean 的过程如下: 首先,接着上面的步骤,在 j2ee 视图中的 ejbModule 下建一个包,并命名为: com.employee.session 然后,再在此包上点右键 -> 新建 -> 其它如下图所示: 然后在弹出的框中选择 EJB-> 企业 Bean ,如下图所示,并选择“下一步” 进入如下图所示,选择好后,单击“下一步” 进入如下图所示画面: 在上图中,选择“会话 bean ”,并在 Bean 名中,输入: EmployeeSession ,并把缺省包选择为: com.employee.session, 然后点击下一步。进入如下图所示: 这里无须变动,直接点击“完成”。 这样,便创建了一个 StateLess SessionBean ,它包括三个文件: Remote 接口: EmployeeSession.java Home 接口: EmployeeSessionHome.java Bean 本身: EmployeeSessionBean.java • 下面我们来修改 SessionBean ,使之对 CMP 实体 BEAN 进行包装。 在 j2ee 视图中,双击 com.employee.session 包下面的 EmployeeSessionBean.java 文件,打开它编辑,在类中增加方法,增加后的 EmployeeSessionBean.java 文件内容如下所示: package com.employee.session; import java.rmi.RemoteException; import java.util.Collection; import java.util.Iterator; import java.util.Vector; import javax.ejb.CreateException; import javax.ejb.FinderException; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import com.employee.com.Employee; import com.employee.com.EmployeeHome; import com.employee.com.EmployeeKey; /** * Bean implementation class for Enterprise Bean: EmployeeSession */ public class EmployeeSessionBean implements javax.ejb.SessionBean { private javax.ejb.SessionContext mySessionCtx; /** * getSessionContext */ public javax.ejb.SessionContext getSessionContext() { return mySessionCtx; } /** * setSessionContext */ public void setSessionContext(javax.ejb.SessionContext ctx) { mySessionCtx = ctx; } /** * ejbCreate */ public void ejbCreate() throws javax.ejb.CreateException { } /** * ejbActivate */ public void ejbActivate() { } /** * ejbPassivate */ public void ejbPassivate() { } /** * ejbRemove */ public void ejbRemove() { } /** * 私有方法,获得实体Bean的Home接口 * @return 返回实体Bean的Home接口对象 */ private EmployeeHome getEmployeeHome(){ InitialContext initialContext = null ; EmployeeHome employeeHome = null ; try { initialContext = new InitialContext(); Object employeeHomeObject = initialContext.lookup( "ejb/com/employee/com/EmployeeHome" ); employeeHome = (EmployeeHome)PortableRemoteObject.narrow(employeeHomeObject,EmployeeHome. class ); } catch (NamingException e){ System.err.println( "CaughtException:" +e.toString()); employeeHome = null ; e.printStackTrace(); } finally { if (initialContext!= null ) try { initialContext.close(); } catch (NamingException e) { } } return employeeHome; } /** * 私有方法:获得一个对应ID的实体Bean实体对象,如果没有找到,则用 * 给定的ID创建一个实体Bean对象 * @param id:给定要查找的对象的id * @return 返回给定ID的一个对应的实体对象 */ private Employee getEmployee( int id){ Employee employee = null ; EmployeeHome employeeHome = this .getEmployeeHome(); try { try { if (employeeHome!= null ){ employee = employeeHome.findByPrimaryKey( new EmployeeKey(id)); } } catch (FinderException e) { System.out.println( "Can not find a Employee with gived id,So try to create one." ); employee = employeeHome.create(id, null , null ); } } catch (Exception e) { System.err.println( "CaughtException:" +e.toString()); employee = null ; e.printStackTrace(); } finally { employeeHome = null ; } return employee; } /** * 远程方法:用给定的信息生成一个实体Bean对象记录。 * @param id:给定需要创建对象的id * @param name:给定要创建对象的name * @param email:给定要创建对象的email * @return 返回成功创建对象的id */ public int createOneEmployee( int id,String name,String email){ EmployeeHome employeeHome = this .getEmployeeHome(); try { if (employeeHome!= null ){ employeeHome.create(id,name,email); } } catch (RemoteException e) { System.err.println( "CaughtException:" +e.toString()); e.printStackTrace(); } catch (CreateException e) { System.err.println( "CaughtException:" +e.toString()); e.printStackTrace(); } finally { employeeHome = null ; } return id; } /** * 远程方法:返回给定id对应对象的name * @param id:给定的id * @return 返回对应id对象的name字符串 */ public String getNameById( int id){ String name = null ; Employee employee = null ; employee = this .getEmployee(id); if (employee!= null ) try { name = employee.getName(); } catch (RemoteException e) { System.err.println( "Can not get Name by given id!" ); employee = null ; e.printStackTrace(); } return name; } /** * 远程方法:返回给定id对应对象的email * @param id:给定的id * @return 返回对应id对象的email字符串 */ public String getEmailById( int id){ String email = null ; Employee employee = null ; employee = this .getEmployee(id); if (employee!= null ) try { email = employee.getEmail(); } catch (RemoteException e) { System.err.println( "Can not get Email by given id!" ); employee = null ; e.printStackTrace(); } return email; } /** * 远程方法:给定一个id和name,将该id对应的name设定为给定的name * @param id:给定的id * @param name,新的name * @return 返回设定对象的id * */ public int setNameById( int id,String name){ Employee employee = null ; employee = this .getEmployee(id); try { employee.setName(name); } catch (RemoteException e) { System.err.println( "Can not set name by given id!" ); employee = null ; e.printStackTrace(); } return id; } /** * 远程方法:给定一个id和email,将该id对应的email设定为给定的email * @param id:给定的id * @param name,新的email * @return 返回设定对象的id * */ public int setEmailById( int id,String email){ Employee employee = null ; employee = this .getEmployee(id); try { employee.setEmail(email); } catch (RemoteException e) { System.err.println( "Can not set email by given id!" ); employee = null ; e.printStackTrace(); } return id; } /** * 远程方法:查找所有的实体Bean对象 * @return 返回查找到的所有的实体Bean对象的id的集合,是Integer保存的 */ public Collection findAllEmployees(){ Vector allId = new Vector(); EmployeeHome employeeHome = this .getEmployeeHome(); try { if (employeeHome!= null ){ Collection allEmployee = employeeHome.findAllEmployees(); Iterator iterator = allEmployee.iterator(); while (iterator.hasNext()){ Employee employee = (Employee) iterator.next(); allId.add( new Integer(employee.getId())); } //end while } //end if } catch (Exception e) { System.err.println( "FindAllEmployees Caught Exception!" ); employeeHome = null ; e.printStackTrace(); } return allId; } /** * 远程方法:给出name查找所有对应的实体Bean对象 * @param name:给定的name * @return 返回查找到的所有的实体Bean对象的id的集合,是Integer保存的 */ public Collection findAllEmployeesByName(String name){ Vector allId = new Vector(); EmployeeHome employeeHome = this .getEmployeeHome(); try { if (employeeHome!= null ){ Collection allEmployee = employeeHome.findByName(name); Iterator iterator = allEmployee.iterator(); while (iterator.hasNext()){ Employee employee = (Employee) iterator.next(); allId.add( new Integer(employee.getId())); } //end while } //end if } catch (Exception e) { System.err.println( "findAllEmployeesByName Caught Exception!" ); employeeHome = null ; e.printStackTrace(); } return allId; } /** * 远程方法:给出email查找所有对应的实体Bean对象 * @param email:给定的email * @return 返回查找到的所有的实体Bean对象的id的集合,是Integer保存的 */ public Collection findAllEmployeesByEmail(String email){ Vector allId = new Vector(); EmployeeHome employeeHome = this .getEmployeeHome(); try { if (employeeHome!= null ){ Collection allEmployee = employeeHome.findByEmail(email); Iterator iterator = allEmployee.iterator(); while (iterator.hasNext()){ Employee employee = (Employee) iterator.next(); allId.add( new Integer(employee.getId())); } //end while } //end if } catch (Exception e) { System.err.println( "findAllEmployeesByEmail Caught Exception!" ); employeeHome = null ; e.printStackTrace(); } return allId; } } • 然后把增加的一些 public 方法提升至远程方法,把下列方法提升至远程方法: createOneEmployee ()、 getNameById 、 getEmailById 、 setNameById 、 setEmailById 、 findAllEmployees 、 findAllEmployeesByName 、 findAllEmployeesByEmail ,提升后,屏幕左下角的轮廓视图如下图所示: 紧接着,对此 SessionBean 进行生成部署代码,在 j2ee 视图中的层次结构下,选中 EmployeeSession ,点右键,生成部署代码,如下图所示: • 注意,我们在上面的 SessionBean 中访问实体 Bean ,是通过查找实体 Bean 的实际的 jndi 名字来获得对实体 Bean 的引用的。同时,实体 Bean 引用数据库连接池也是使用数据库连接的 jndi 名字来引用数据库连接的。 然而,在许多时候,我们可以使用“资源映射”来访问实体 Bean ,也就是说: SessionBean 在访问实体 Bean 的时候,采用 lookup(“java:comp/env/Employee”) 来查找实体 Bean ,而这里的查找是采用 j2ee 推荐的标准名字空间,这里的 Employee 是一个别名,在这里它对应着我们的 Employee 实体 Bean ,这个对映关系由资源映射符来确定,也就是说资源映射符定义了这里的别名 Employee 和实体 Bean 的 Employee 的 jndi 之间的对应关系。这种使用方式的优点是,在程序中可以写死调用的别名,具体实际调用的是哪一个 EJB 由布署时在资源映射符中定义。 如果你接受以上用法会给你的 EJB 开发和部署带来好处,那么请继续看下去如何做来定义这些资源引用,如果你不接受这个观点,你认为在程序中将 EJB 的 jndi 名字写死,那么请跳过下一段,直接进入 18 小节阅读。 好,下面我们来看如何修改我们的 SessionBean ,使之采用资源映射的方式来访问我们的实体 Bean 。第一步,修改代码,打开 EmployeeSessionBean.java 文件,找到其中的: private EmployeeHome getEmployeeHome() 方法,把它修改成如下所示: private EmployeeHome getEmployeeHome(){ InitialContext initialContext = null ; EmployeeHome employeeHome = null ; try { initialContext = new InitialContext(); //Object employeeHomeObject = initialContext.lookup("ejb/com/employee/entity/EmployeeHome"); //采用资源引用,不直接采用jndi查找 Object employeeHomeObject = initialContext.lookup( "java:comp/env/EmployeeRef" ); employeeHome = (EmployeeHome)PortableRemoteObject.narrow(employeeHomeObject,EmployeeHome. class ); } catch (NamingException e){ System.err.println( "CaughtException:" +e.toString()); employeeHome = null ; e.printStackTrace(); } finally { if (initialContext!= null ) try { initialContext.close(); } catch (NamingException e) { } } return employeeHome; } 在上面的代码中,我们只修改了一句,把原来采用 jndi 来查找实体 Bean 的方法改为了采用资源引用的方式,在这里,我们用 EmployeeRef 这个别名来引用实体 Bean 。 下面我们来修改部署描述符文件,增加资源引用部分。在 WSAD 左边 j2ee 视图中的 j2ee 层次结构视图中,打开 EJB 模块下的会话 Bean ,双击其下的 EmployeeSession ,在右边的视图中打开其部署描述符文件,选择“引用”页面,如下图所示: 选择 EmployeeSession ,然后单击其下方的“添加”按钮,如下图所示: 选中“ EJB ”引用,点击“下一步”,如下图所示: 在上图中,选择“当前 EJB 项目中的企业 bean ”,然后在列表中选择中“ Employee ”,并把系统在“名称”中填入的 ejb/Employee 修改为“ EmployeeRef ”,这是我们在程序中引用的别名。然后点“下一步”,并在下一步中点“完成”。重新回到了部署描述符文件中。如下图所示:系统自动填写完毕。 保存并退出部署描述符修写。 重新生成 EmployeeSession 的部署代码,并重新编译 EJB 。 • 然后,我们可以像第 11 步中那样启动通用测试客户机来测试我们的的 SessionBean 。在 J2ee 视图中的 j2ee 层次结构中,选中 EmployeeSession ,点右键,在服务器上运行即可。 • • 性能优化,在这一小节中,我们来看看如何优化 SessionBean 来调用实体 Bean 的性能,由于 SessionBean 通过远程接口 lookup 实体 Bean ,所以大部分时间均发在 lookup 上面了。为了优化 SessionBean 调用实体 Bean 的性能,我们在这里给出一个参考方案即采用“重用 Home 句柄”技术。也就是将需要在 SessionBean 中调用的实体 Bean 的 home 句柄用缓存保存起来,为了达到这个目地,我们需引入单根模式来设计一个 EjbHomeCacheHelper 类。 在 j2ee 视图中,像前面编写 SessionBean 一样,新建一个包并命名为: com.ejbhome.helper ,然后再在此包在新建一个类,并命名为: EjbHomeCacheHelper ,其全部代码如下:(其代码是自解释的) package com.ejbhome.helper; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import com.employee.entity.EmployeeHome; /** * @author abnerchai * 本方法采用单根模式来存储所有的实体Bean的Home句柄,这样系统中有 * 多少个实体Bean,那么在本对象中就存储了多少个Home对象柄,在本对象 * 第一次初始化时就将所有的实体Bean的Home句柄保存起来放在内存中,下一次其它的 * SessionBean欲调用实体BEAN时,只需从内存中获得即可,这样可以大大提高调用的 * 速度和性能。 */ public class EjbHomeCacheHelper { //定义所有的对实体Bean的引用名字在这里,有几个实体Bean,这里就定义几个引用常量 private static final String EmployeeRef = "EmployeeRef" ; //采用单根模式 private static EjbHomeCacheHelper ejbHomeCache = null ; //定义保存所有Home句柄引用的表 private Hashtable ejbHomeTable = new Hashtable(); //采用单根模式,将构造器设置为私有的 private EjbHomeCacheHelper(){ } //返回表 private Hashtable getejbHomeTable(){ return ejbHomeTable; } private synchronized static EjbHomeCacheHelper getInstance(){ if (ejbHomeCache == null ){ //第一次运行为空,便构建一个,以便所有的共享 ejbHomeCache = new EjbHomeCacheHelper(); //构建实体BEAN柄集合 ejbHomeCache.buildHomeHandleCache(); } return ejbHomeCache; } //构建出所有的实体Bean的Home句柄的集合并保存起来 private void buildHomeHandleCache(){ Context ctx = null ; Object homeObject = null ; EmployeeHome employeeHome = null ; Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory" ); try { ctx = new InitialContext(env); homeObject = ctx.lookup( "java:comp/env/EmployeeRef" ); employeeHome = (EmployeeHome)PortableRemoteObject.narrow(homeObject,EmployeeHome. class ); getejbHomeTable().put(EmployeeRef,employeeHome); //可以在这里加入其它的对实体Bean的引用并把它放入cache表中,需要引用几个实体Bean, //这里就加上几个查找并put的方法 } catch (Exception e){ e.printStackTrace(); } finally { if (ctx!= null ){ try { ctx.close(); } catch (NamingException e1) { e1.printStackTrace(); } } //end if } //end finally } //end buildHomeHandleCache //以下所有的方法对外开放,用于外部引用实体Bean时获得实体Bean的Home句柄 //有几个实体Bean,这里就定义几个方法 public static EmployeeHome getEmployeeHome(){ return (EmployeeHome)getInstance().getejbHomeTable().get(EmployeeRef); } } //end class 然后,我们就采用这个工具类来调用我们的实体 Bean 了,在 EmployeeSessionBean.java 文件中新增一个方法:名字为: getEmployeeHomeFromCache() ,其内容如下: /** * 私有方法,通过实体Bean缓存来获得EmployeeHome接口 * 可以大大提高性能 * @return 返回实体Bean的Home接口对象 */ private EmployeeHome getEmployeeHomeFromCache(){ return EjbHomeCacheHelper.getEmployeeHome(); } 即可。在需要调用实体 Bean获得Home的地方,采用此方法替换即可。 • 下面我们来开发一个 JavaBean 和一个 JSP 页面来调用我们的 EJB ,过程如下: 在 J2ee 视图中,点菜单中的“文件” -> “新建” -> “项目”,如下图所示: 选择左边的 WEB ,选择中右边的“动态 Web 项目” , 点下一步。如下图所示: 在项目名中填写 HelloWorldWebProject ,并选择中“配置高级选项”然后点“下一步”即可如下图所示: 按上图中所示选择 EAR 项目为己有的 HelloWorldEARProject ,上下文根不变即可。然后点“下一步”,如下图所示: 在上图中什么也不选择,直接点击“完成”,在弹出的两个如下图所示的对话框中,选择“确定修改服务器配置”和“不切换到 WEB 视图”即可。 然后,在 WSAD 左边 J2ee 视图中出现了如下图所示的情况: 在上图中,在当前 EAR 项目中新建了一个 WEBProject 项目,这个 WEB 项目下面包括两部分:一个是 Java Source ( Java 资源),另一个是 Web Content 。前者用于管理和存放 JavaBean 及 Servlets ,后者用于存放和管理 JSP 及 HTML 等页面文件。 接着在上图中,右键选中“ java 资源”,点击右键菜单中,选择“新建” -> “包”如下图所示: 弹出如下图所示对话框: 在上图中名称栏中输入: ”com.employee.bean” 包名。点完成即可。然后再在左边的 J2ee 视图中选择刚建好的包,点右键,“新建” -> “类”如下图所示: 弹出如下图所示对话框: 在此图中,名称一栏中填入“ EmployeeJavaBean ”做为我们的 JavaBean 名字,然后点“完成”即可打开编辑这个 JavaBean 的代码窗口。 此时,右键点击 J2ee 视图中的 EmployeeWebProject ,选择“属性”,然后在弹出的对话框中左边选择“项目引用”,如下图所示: 右边请选择中 HelloWorldEJBProject ,。接着,选择这个图左边的“ Java 构建路径”,在右边出来的窗口中选择中“项目”一页,如下图所示: 在上图中选中“ HelloWorldEJBProject ”,然后点确定。这样一来,我们的 WEB 项目就可以调用 EJB 了。下面我们来编写 javaBean 我们这个 EmployeeJavaBean 是用来提供给 JSP 页面来调用 EJB 的。编写后的代码如下所示: package com.employee.bean; import java.rmi.RemoteException; import java.util.Hashtable; import javax.ejb.CreateException; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import javax.servlet.http.HttpServletRequest; import com.employee.session.EmployeeSessionHome; import com.employee.session.EmployeeSession; public class EmployeeJavaBean { private HttpServletRequest _request = null ; public void init(HttpServletRequest req){ this ._request = req; } private EmployeeSession getEmployeeSession(){ Context ctx = null ; Object homeObject = null ; EmployeeSessionHome employeeSessionHome = null ; EmployeeSession employeeSession = null ; Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory" ); try { ctx = new InitialContext(env); homeObject = ctx.lookup( "ejb/com/employee/session/EmployeeSessionHome" ); employeeSessionHome = (EmployeeSessionHome)PortableRemoteObject.narrow(homeObject,EmployeeSessionHome. class ); employeeSession = employeeSessionHome.create(); } catch (Exception e){ e.printStackTrace(); } finally { if (ctx!= null ){ try { ctx.close(); } catch (NamingException e1) { e1.printStackTrace(); } } //end if } //end finally return employeeSession; } public String getNameByEmployeeID(){ String id = this ._request.getParameter( "ID" ); if (id== null ) return null ; int int_id = Integer.parseInt(id); String name = null ; try { name = this .getEmployeeSession().getNameById(int_id); } catch (RemoteException e) { e.printStackTrace(); } return name; } } 注意,为了演示,我在 JavaBean 中只编写了一个方法,该方法来调用 SessionBean 中的方法。 下面我们新建一个 JSP 文件,来调用我们的 JavaBean ,过程如下: 在 J2ee 视图中,右键选中 WebContent , ” 新建 ”-> “ JSP 文件”如下图所示: 在弹出的对话框中如下图: 填入文件名为 index.jsp 。然后点击完成。进入编辑 JSP 页面。 修改后的 JSP 文件代码如下所示: <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > < HTML >< HEAD > <%@ page language = "java" contentType = "text/html; charset=GBK" pageEncoding = "GBK" %> < jsp:useBean id = "employeeJB" class = "com.employee.bean.EmployeeJavaBean" scope = "page" ></ jsp:useBean > < META http-equiv = "Content-Type" content = "text/html; charset=GBK" > < META name = "GENERATOR" content = "IBM WebSphere Studio" > < TITLE > index.jsp </ TITLE > </ HEAD > < BODY > <% String name = null ; if (request.getMethod().equalsIgnoreCase( "post" )){ employeeJB.init(request); name = employeeJB.getNameByEmployeeID(); } %> < p > 请输入你要查找的ID: </ p > < form name = "base" method = "POST" action = "index.jsp" > < input type = "text" value = "" name = "ID" > < input type = "submit" value = "查找!" > </ form > <% if (name!= null ){ out.println( "<p>你查找的名字是:" +name+ "</p>" ); } %> </ BODY > </ HTML > • 测试: 启动服务器,在 IE地址栏中输入: http://localhost:9080/HelloWorldWebProject/index.jsp ,在输入框中输入1,运行如下图所示: • 这里,我们的 JavaBean采用的是直接调用SessionBean,在实际的运用中,我们也可以采用前面所说的“重用Home句柄”的方法来提搞性能。 首先,我们修改我们的 JavaBean,使其采用资源引用的方式来调用SessionBean,方法如下: 打开 EmployeeJavaBean .java文件,修改其中的 private EmployeeSession getEmployeeSession() 方法。把这个方法中的: homeObject = ctx.lookup("ejb/com/employee/session/EmployeeSessionHome"); 替换为: homeObject = ctx.lookup("java:comp/env/EmployeeSessionRef"); 然后,再在左边 J2ee视图中,双击打开 ” WEB CONTENT ” 目录下的 ” WEB-INF ” 目录下的 web.xml,启动WEB部署符编辑器,然后选择中页面“引用”如下图所示: 在上图中,单击“添加” ,并修改自动产生的引用的名字为:“ EmployeeSessionRef ”,然后选中它,在右边的框中输入必要的信息,方法如下:在链接右边单击“浏览”,弹出如下图所示的对话框: 双击图中的 EmployeeSession,即可。WSAD自动把图中的框填充完毕。如下图所示,保存即可。 至此,我们己把 JavaBean调用SessionBean改为了资源引用的方式。 下面,我们来采用“重用 Home句柄”的方式来优化JavaBean调用SessionBean的性能。 • 为了提高 JavaBean调用SessionBean(EJB)的性能,采用同样的方式,我们先在“Java资源”下新建一个包并命名为:com.bean.ejbhelper,并在包中新建一个类,命名为: EjbHomeFindCacheHelper 其源代码如下: package com.bean.ejbhelper; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.rmi.PortableRemoteObject; import com.employee.session.EmployeeSession; import com.employee.session.EmployeeSessionHome; public class EjbHomeFindCacheHelper { //定义所有的对SessionBean的引用名字在这里,有几个SessionBean,这里就定义几个引用常量 private static final String EmployeeSessionRef = "EmployeeSessionRef" ; //采用单根模式 private static EjbHomeFindCacheHelper ejbHomeCache = null ; //定义保存所有Session句柄引用的表 private Hashtable ejbHomeTable = new Hashtable(); //采用单根模式,将构造器设置为私有的 private EjbHomeFindCacheHelper(){ } //返回表 private Hashtable getejbHomeTable(){ return ejbHomeTable; } private synchronized static EjbHomeFindCacheHelper getInstance(){ if (ejbHomeCache == null ){ //第一次运行为空,便构建一个,以便所有的共享 ejbHomeCache = new EjbHomeFindCacheHelper(); //构建SessionBean句柄集合 ejbHomeCache.buildHomeHandleCache(); } return ejbHomeCache; } //构建出所有的SessionBean的Home句柄的集合并保存起来 private void buildHomeHandleCache(){ Context ctx = null ; Object homeObject = null ; EmployeeSessionHome employeeSessionHome = null ; Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory" ); try { ctx = new InitialContext(env); //通过在web.xml中配置资源引用来查找EJB homeObject = ctx.lookup( "java:comp/env/" +EmployeeSessionRef); employeeSessionHome = (EmployeeSessionHome)PortableRemoteObject.narrow(homeObject,EmployeeSessionHome. class ); getejbHomeTable().put(EmployeeSessionRef,employeeSessionHome); //可以在这里加入其它的对SessionBean的引用并把它放入cache表中,需要引用几个SessionBean, //这里就加上几个查找并put的方法 } catch (Exception e){ e.printStackTrace(); } finally { if (ctx!= null ){ try { ctx.close(); } catch (NamingException e1) { e1.printStackTrace(); } } //end if } //end finally } //end buildHomeHandleCache //以下所有的方法对外开放,用于外部引用实体Bean时获得实体Bean的Home句柄 //有几个实体Bean,这里就定义几个方法 public static EmployeeSessionHome getEmployeeSessionHome(){ return (EmployeeSessionHome)getInstance().getejbHomeTable().get(EmployeeSessionRef); } } 定义好了这个类以后,我们再次修改我们的 JavaBean,打开 EmployeeJavaBean .java文件,增加一个方法如下: private EmployeeSession getEmployeeSessionByCache(){ EmployeeSessionHome employeeSessionHome = null ; EmployeeSession employeeSession = null ; employeeSessionHome = EjbHomeFindCacheHelper.getEmployeeSessionHome(); try { employeeSession = employeeSessionHome.create(); } catch (Exception e) { e.printStackTrace(); } return employeeSession; } 即可,然后把原来调用 getEmployeeSession ()的地方改为 getEmployeeSessionByCache ()即可。 测试方法同前一样 ,在此不再详解。最后,你的工作区形成了如下图所示的情况: • 到此为止,我们详细说明了一个 CMP实体Bean的开发过程及其客户端的开发过程。 希望你能有所收获。任何意见和建议请和我联系。 四、CopyrightCopyright by abnerchai, 2004. you can contact me at: [email protected] |