用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(下篇:客户端的开发和性能优化)
来源:互联网 发布:三国志11 高长恭数据 编辑:程序博客网 时间:2024/05/17 06:38
用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发
CMP实体Bean及其完整客户端
(下篇:客户端的开发和性能优化)
接上篇:
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的开发过程及其客户端的开发过程。
希望你能有所收获。任何意见和建议请和我联系。
四、Copyright
Copyright by abnerchai, 2004. you can contact me at: abnertsai@sina.com
- 用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(下篇:客户端的开发和性能优化)
- 用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(上篇:CMP的开发)
- 实体Bean的BMP和CMP选择
- 配置CVS服务器、客户端和使用CVS开发项目的终极完美教程(下篇)
- 开发第一个ejb2.0实体bean CMP
- Enterprise JavaBeans 入门 实体 Bean 和 CMP
- Unity客户端框架笔记二(组件实体开发模式的思考)
- Android访问WCF(下篇)-客户端开发
- 实体bean的开发
- 实体bean的开发
- 基于Apache mina开发的windows客户端和android客户端
- 开发实体EJB 增强的性能和开发
- 数据库的客户端开发,OLEDB和ADO
- gSoap 服务器和客户端的开发
- 简单服务端和客户端的开发
- gSoap 服务器和客户端的开发
- 用WinINet Api 开发FTP客户端 (三) ------ 完整代码
- Meet in the middle
- 用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(上篇:CMP的开发)
- csdn的blog有问题啊
- 如何在.cs中执行*.sql文件,来创建数据库
- 如何才能把我以前别的网站上的Blog搬过来呀?
- OBE的下载与编译过程
- 用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(下篇:客户端的开发和性能优化)
- 热烈庆祝Blog开通
- 6月23日,我自己的blog开通了
- Jsp to Servlet,返回将送的所有值都传回来
- 使用 Microsoft .NET 构建分布式应用程序
- 江苏软件园拉电
- 开张大吉,发发贴,以表纪念
- Hello,everyone!
- 改进版通视卡股票接收VB、delphi演示程序