我们知道,在EJB中最有价值的部分是无状态Session Bean(SLSB)和MDB(消息驱动Bean)。最近公司交给我一个模块来完成,是过去的系统,典型的使用EJB的方式,利用SLSB作为一个门面,业务逻辑封装在普通javabean里面,持久层使用公司自己的一个基础框架。分析如下:
首先是一个公用的SLSB,做为业务层的门面(Facade),如:
远程接口:
import javax.naming.NamingException;
import java.sql.SQLException;
import java.util.Hashtable;
/**
* Remote interface for Enterprise Bean: Test_common
*/
public interface Test_common extends javax.ejb.EJBObject {
/**
*公用业务调用方法
*@param 调用的代码定义
*@param 调用的参数
*@return 返回Hashtable
*/
public Hashtable getBusiness(String vs_code, Hashtable vt_cs)
throws NamingException, SQLException, java.rmi.RemoteException;
}
其中的vs_code指的是调用的模块代码,而vs_cs是一个HashMap,用来传递参数到业务层。
HOME接口:
public interface Test_commonHome extends javax.ejb.EJBHome {
/**
* Creates a default instance of Session Bean: IQS_common
*/
public iqsEjb.common.Test_common create()
throws javax.ejb.CreateException, java.rmi.RemoteException;
}
很明显,不废话,接下来就是BEAN部分,这才是关键:
import testejb.model1.Test1;
import testejb.model2.Test2;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.StringTokenizer;
import javax.naming.NamingException;
/**
* Bean implementation class for Enterprise Bean:Test_common
*/
public class Test_commonBean 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() {
}
/**
*公用业务调用方法
*@param 调用的代码定义
*@param 调用的参数
*@return 返回Hashtable
*/
public Hashtable getBusiness(String vs_code, Hashtable vt_cs)
throws NamingException, SQLException {
Hashtable tab = null; //结果集
int i = 0;
String xt = ""; //模块代码
int oper = 0; //逻辑方法代码
vs_code = vs_code.toLowerCase();
StringTokenizer tok = new StringTokenizer(vs_code, "@");
while (tok.hasMoreTokens()) {
if (i == 0)
xt = tok.nextToken();
if (i == 1)
oper = Integer.parseInt(tok.nextToken());
i++;
}
if (xt.equals("testejb_model1_test")) {
//模块1
Test1 test=new Test1(oper,vt_cs); //注意了,传入参数和所调用逻辑方法的代码
tab = test.getResult();
} else if (xt.equals("testejb_model2_test")) {
//模块2
Test2 test=new Test2(oper,vt_cs);
tab = test.getResult();
}
return tab;
}
}
在业务逻辑方法里面,我们首先解析传进来的模块代码,然后进行判断,调用相应的普通javabean。我们传入的模块代码像这样:testejb_model1_test@1,1代表此模块的某一业务逻辑方法的代码。是不是有点晕?呵呵,等我下面再详细谈。好了,门面最好了,接下来就是具体的业务逻辑了,比如模块1的Test1逻辑:
package testejb.model1;
public class Test1 {
private Hashtable tab = new Hashtable(); //返回的结果集
private Hashtable cs = null; //传入的参数集
public Test1(int vi_oper, HashMap vs_cs) {
cs = vt_cs;
switch (vi_oper) { //根据逻辑方法代码,调用相应方法
case 1 :
{
HelloWorld(); //方法一
break;
}
case 2 :
{
HelloWorld2(); //方法2
break;
}
default :
break;
}
}
public void Helloworld() {
tab.put("1", "Hello World!"+(String)cs.get("name"));
/ /返回结果HelloWorld+姓名,1是给这个结果一个标记,好在servlet中取得
}
public void Helloworld2() {
tab.put("1", "Shit Hello World!"+(String)cs.get("name"));
//返回结果Shit HelloWorld+姓名,1是给这个结果一个标记,好在servlet中取得
}
public Hashtable getResult() { //返回结果集
return tab;
}
}
如你所见,我们把业务逻辑写在这个普通的javabean里面,这是模块1的业务逻辑,你当然可以照着写模块2,每增加一个模块,就在Test_commonBean增加一个:
else if(xt.equals(模块名)){ 创建业务逻辑对象,返回结果集}
好了,SLSB和业务逻辑都写好了,该怎么调用呢?假设我们在servlet中调用此SLSB,典型的代码如下:
Hashtable tab = new Hashtable(); //作为即将传入的参数集合,在这个例子中就是名字咯
try {
Context context = new InitialContext();
Test_commonLocalHome home =
(Test_commonLocalHome) context.lookup("java:comp/env/testcommonbean");
Test_commonLocal remote = home.create();
PrintWriter out = resp.getWriter();
String vs_name = req.getParameter("vs_name"); //获得界面传入的name值
tab.put("name", vs_name); //没忘了吧?我们在Test1中通过cs.get("name")获得参数
String vs_result =
(String) remote.getBusiness(//传入参数集和模块代码,注意这个1,我们调用case 1对应的方法
"testejb_model1_test@1", tab).get("1");
out.print(vs_result);
out.flush();
out.close();
} catch {
...}
注意上面的注释,应该很清楚了吧:)输出结果为HelloWorld+你传入的姓名,如果把testejb_model1_test@1改成testejb_model1_test@1就调用case 2对应的方法,即HelloWorld2()方法,如果改成testejb_model2_test@1那就意味着调用模块2中的业务逻辑了。传入和返回的信息都是用HashMap封装。
呵呵,自己分析了下,对那个项目的理解更深入了点,这也应该是使用SLSB的一个典型方法了。值的学习。