用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(下篇:客户端的开发和性能优化)

python轮胎缺陷检测_基于深度学习的轮胎缺陷无损检测与分类技术研究 基于深度学习的轮胎缺陷无损检测与分类技术研究【摘要】:随着汽车行业快速发展及汽车保有量的持续增长,大大增加了对轮胎的需求,而轮胎质量在很大程度上决定了轮胎的使用寿命,也是在行驶过程中对人们生命财产安全的保障,同时对轮胎进行在线质量检测也便于轮胎生产企业及时发现生产线中存在的不合格产品,以此来调整机械设备甚至轮胎的生产工艺,避免造成生产材料的浪费。因此,检测轮胎质量是轮胎生产过程中必不可缺少的一部分... 阅读详情

用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发
CMP实体Bean及其完整客户端

(下篇:客户端的开发和性能优化)

abnerchai( 柴政 ) 2004 年 6 月

接上篇:

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

基于FMCW技术的毫米波雷达测速原理与应用 调频连续波(FMCW)技术是毫米波雷达中实现高精度测速的核心方法之一。本文详细介绍了FMCW测速的基本原理、信号处理流程以及在实际应用中的关键技术。通过分析FMCW雷达的多普勒效应频率差测量方法,本文展示了如何利用FMCW技术实现目标速度的高精度检测。此外,本文还探讨了FMCW测速在自动驾驶、智能交通工业自动化等领域的应用案例,为毫米波雷达开发者提供了理论支持实践指导。 阅读详情

相关推荐

汇川AM系列ethercat控制伺服的使用说明(含转矩模式)

本文以一个实际例子,介绍ethercat伺服驱动器的工作原理,以及在汇川AM系列PLC中,如何点动、定位、速度、转矩控制ethercat伺服。

qq_34047402的博客 5061

WSAD5.0SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(上篇:CMP开发

无标题文档 用 WSAD5.0SQLServer2K采用Meet-in-Middle模式 开发CMP实体Bean及其完整客户端 (上篇:CMP开发) abnerchai( 柴政 ) 2004 年 6 月 说明: 在许多情况下,我们现在还常常使用 CMP 实体 Bean ,而 IBM 的 WebSphere Studio Application Developer5.0

abnerchai的生活和技术日志 2640

YOLOv12模型详解及代码复现

YOLOV12算法详解及Python代码复现

hasakie的博客 6456

理解正确使用Java中的断言(assert)

理解正确使用Java中的断言(assert) 一、语法形式:    Java2在1.4中新增了一个关键字:assert。在程序开发过程中使用它创建一个断言(assertion),它的语法形式有如下所示的两种形式:1、assert condition;    这里condition是一个必须为真(true)的表达式。如果表达式的结果为true,那么断言为真,并且无任何行动如果表达式为false,则

abnerchai的生活和技术日志 1万+

深入剖析Java编程中的中文问题及建议最优解决方法--上篇

深入剖析Java编程中的中文问题及建议最优解决方法--上篇 说明:本文为作者原创,作者联系地址为:josserchai@yahoo.com。由于Java编程中的中文问题是一个老生常谈的问题,在阅读了许多关于Java中文问题解决方法之后,结合作者的编程实践,我发现过去谈的许多方法都不能清晰地说明问题及解决问题,尤其是跨平台时的中文问题。于是我给出此篇文章,内容包括对控制台运行的class、

abnerchai的生活和技术日志 7576

Jbuilder9.0+jboss-3.2.1_tomcat-4.1.24.zip+MySql/MS SQL Server2K开发环境配置手记

Jbuilder9.0+jboss-3.2.1_tomcat-4.1.24.zip+MySql或MS SQL Server2K开发环境配置手记 网络上对Jbuilder9.0+JBOSS-3.2开发环境的配置说明的参考还很少,我在这里提供一个,请大家参考,并指教!这是我在配置这个开发环境时的一个手记。下面是详细步骤: 1、 安装Jbuilder9.0到D:/Jbuilder9目录2、 安

abnerchai的生活和技术日志 4584

win2k环境下基于JBOSS的J2EE开发实践----之一初始基础环境的配置与测试

JBOSS开发实践 基于 win2k环境下的JBOSS开发实践         之一:初始基础开发环境的配置与测试 说明: 此节针对 ejb 开发初学者,主要是手动配置一个最基本的基于文本开发的环境,让初学者从头开始编写各类程序配置文件,以更清楚的了解 EJB 开发部署的步聚与原理。这是作者在学习 EJB 开发时的一个总结,欢迎指正。作者联系地址址: josse

abnerchai的生活和技术日志 4064

深入剖析Java编程中的中文问题及建议最优解决方法---下篇

New Document 深入剖析Java编程中的中文问题及建议最优解决方法 说明:本文为作者原创,作者联系地址为:josserchai@yahoo.com。由于Java编程中的中文问题是一个老生常谈的问题,在阅读了许多关于Java中文问题解决方法之后,结合作者的编程实践,我发现过去谈的许多方法都不能清晰地说明问题及解决问题,尤其是跨平台时的中文问题。于是我给出此

abnerchai的生活和技术日志 4043

win2k环境下基于JBOSS的J2EE开发实践----之五:CMP实体Bean的编写与部署

win2k环境下基于JBOSS的J2EE开发实践 ----之五:CMP实体Bean的编写与部署一、 前言在前面一系列文章的上一节中,我们给出了编写BMP的方法,并详细述说了BMP与CMP的区别共性。BMPCMP同属EJB2.x规范中定义的实体Bean(Entity Bean),一个实体Bean是由多个类接口组成,我们可以认为一个实体Bean代表数据库中的一个表(姑且这么认为),一个实体Bea

abnerchai的生活和技术日志 3756

win2k环境下基于JBOSS的J2EE开发实践----之四:BMP实体Bean的编写与设计

win2k环境下基于JBOSS的J2EE开发实践     ----之四:BMP实体Bean的编写与设计说明:本教程发表于csdn.net网站(中国程序员网)文档中心,任何人转载请注明出处,并且保留此说明。作者本人在发表此系列文章后,许多网友来信要求作者继续编写此教程,作者在此处首先感谢广大网友的信任!作者联系地址为:josserchai@yahoo.com。前言: 在《WIN2k环境下基于JBOS

abnerchai的生活和技术日志 3509

深入理解嵌套类内部类

深入理解嵌套类内部类 一、什么是嵌套类及内部类?    可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。嵌套类从JDK1.1开始引入。其中inner类又可分为三种:    其一、在一个类(外部类)中直接定义的内部类;    其二、在一个方法(外

abnerchai的生活和技术日志 3504

win2k环境下基于JBOSS的J2EE开发实践----之三、有状态会话 Bean开发及多种调用有状态会话Bean方法的实现

win2k环境下基于JBOSS的J2EE开发实践 ----之三、有状态会话 Bean开发及多种调用有状态会话Bean方法的实现 说明:此节是继上一节之后所写,在上两节中我们实现了 JBOSS 开发平台的配置及数据库连接池的配置,同时我们在第一节的示例中,给出了一个无状态会话 Bean 的实例 HelloWorld 。这一节中我们接着学习 EJB 开发。 注意:本

abnerchai的生活和技术日志 3479

win2k环境下基于JBOSS的J2EE开发实践-----之二、数据库连接池的配置与测试

JBOSS开发实践 基于 win2k环境下的JBOSS开发实践         之二、数据库连接池的配置与测试 说明:此节是在上一节基础之上写的,上一节中我们把JBOSS服务器配置好,并测试通过了。这一节我们来看看怎么样在JBOSS中 用JspServlet连结数据库,并使用它的连接池,你一定要在看完上节后再看这一节。 一、配置MySQL数据库 1、安装

abnerchai的生活和技术日志 3216

一个经试用效果非常不错的数据库连接池

无标题文档 一个经试用效果非常不错的数据库连接池 前言: 虽说现在许多企业级的应用服务器均自己带有数据库连接池功能,就连 Tomcat 也支持了这种功能。然而在许多时候,我们还是要使用数据库连接池,如:访问数据库的 Java 桌面应用程序等。这个数据库连接池是我根据《 Inside Servlets 》一书中的示例改写而成,经过试用,效果非常不错。特发布共享。 ( 作者

abnerchai的生活和技术日志 2878

JAVA中通用JPEG缩影图Bean的制作与示例

JAVA中通用JPEG缩影图Bean的制作与示例 JAVA中通用JPEG缩影图Bean的制作与示例 说明: 前一段时间,看到网上一个网友贴出一个用 Java 跨平台的生成 Jpeg 图片缩影图的方法。最近整理了一下,形成了一个通用的类。并制作成一个 jar 包。以方便重用。并给出了使用示例。(作者: abnerchai ;联系: josserchai@yahoo.com

abnerchai的生活和技术日志 2606

Tomcat7.0.40 基于DataSourceRealm的JDBCRealm的资源用户访问控制

软件版本: Tomcat 7.0.40 Mysql: 5.1 Host: CentOS 6.3 64bit 使用JDBCRealm (Tomcat 会使用所给的JDBC Connecter 自己去连MySQL 数据库并进行用户验证): 1) 下载MySQL-JDBC connector 如mysql-connector-java-5.1.24-bin.jar放到$CATALI

abnerchai的生活和技术日志 1484

直播APP如何兼顾画质与低延迟?视频美颜SDK性能优化开发思路

直播APP既要高清画质,又要低延迟流畅体验,美颜SDK的性能优化就成为关键环节。本文从视频处理链路、GPU加速、人脸识别、动态降级、多机型适配等方面,分析直播APP开发中如何优化视频美颜SDK,在保证美颜效果的同时降低设备负载处理延迟。

wanyuekeji的博客 224

12-Rust 性能优化指南(性能分析 + 内存优化 + SIMD + 并发优化 + 编译器优化 + 基准测试)

本文系统讲解 Rust 性能优化核心知识,涵盖性能分析工具(perf、flamegraph、cachegrind)、内存优化(零拷贝、缓存友好、内存池)、SIMD 向量化、并发优化(线程池、无锁数据结构)、编译器优化标志、基准测试(criterion)等核心内容。每个知识点配有完整代码示例、对比表格、实战场景及常见问题解答,帮助开发者编写高性能 Rust 代码。

2301_78939167的博客 676

【ArkUI 练中学】第14课:应用性能优化实战

本文系统阐述ArkUI应用性能优化核心方法:以冷启动≤3000ms、点击响应≤1000ms、帧率≥60为目标,通过HiTrace+DevEco Profiler获取关键路径瀑布图,运用“延迟、并行、裁剪、预置”四步法优化启动链路。结合细粒度状态管理、组件拆分、@Reusable复用、LazyForEach懒加载等手段提升渲染效率,遵循扁平化布局原则减少重绘,利用工具链检测内存泄漏,实施资源压缩、HSP共享与分包策略降低包体积,并建立“分析—优化—验证”闭环,实现全链路性能治理。

jackchuanqi的博客 131

5板块·第4节:性能优化中的高级技巧

恭喜你完成第5板块「Kernel全方位性能优化(调优实战)」的全部内容!测量→假设→优化→验证迭代闭环;Nsight Systems / Compute工具分工。✅ 基于Profiling迭代实战:解读报告,针对内存/依赖/同步/执行单元各类Warp停滞做针对性优化;识别调优陷阱。✅ 典型算子深度优化:GEMM多级优化、im2col卷积、FlashAttention分块重计算思想。cp.async异步拷贝流水线双缓冲;CUDA Graph消除Kernel启动开销;多流并发;架构适配;

qq_19988687的博客 350

【ArkUI 练中学】第18课:性能优化进阶与工程化治理

本文系统介绍了HarmonyOS应用性能治理全链路方案:基于DevEco Profiler的场景化分析模板(如Launch、Frame、Time等)实现精准问题定位;通过深度录制与跨语言调用栈分析优化关键路径;结合Test Kit与DevEco Testing构建白盒自动化测试与性能基线;利用HiAppEvent+AGC APMS实现线上启动耗时、崩溃率等指标监控;针对折叠屏等多设备形态,采用响应式布局与布局重算控制策略;最终将性能门禁融入CI/CD,形成“开发—测试—上线”闭环治理能力,助力中型应用实现高

jackchuanqi的博客 156
上一篇: 用 WSAD5.0和SQLServer2K采用Meet-in-Middle模式开发CMP实体Bean及其完整客户端(上篇:CMP的开发)
下一篇: Java安全通信、数字证书及数字证书应用实践
AbnerChai
博客等级 码龄24年 21粉丝 30原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值