那么首先我们要讲到的是SessionBean就是会话Bean。
在MVC模型当中,J2EE程序通常是以JSP来充当显示层、Servlet来充当控制层、JavaBean用来充当模型层。当我们使用EJB体系后,模型层就使用EJB组件来充当。
模型层也就是用来处理业务逻辑,而业务逻辑在系统中可简单的分为两类:
一、信息处理和流程控制
二、数据库操作
而我们所要讲到的SessionBean就是用来处理信息和流程控制的。
会话Bean表示为业务进程,一般用来封装企业应用的业务逻辑。比如:计算购买总价,货币利率转换等等。
根据会话Bean的类型我们可以把它分为两类:
一、无状态会话Bean
二、有状态会话Bean
无状态会话Bean,主要是用来处理单纯的业务逻辑。比如计算总价,获得金额,统计等等。多个用户可以同时并反复的调用这个会话Bean的同一个实例。也就是共享同一个实例来完成业务逻辑。
而有状态会话Bean,需要保留用户的会话状态。换句话说在特定的条件下一个用户只对应一个有状态的会话Bean的实例。比如购物车,一个用户就必须对应一个有状态的会话Bean的实例,这个实例保存了这个用户所购买了的所有产品。而且每个用户都买的产品都不一样,所以他们不能共享实例。
再者就是二者的生命周期不同。
哪么如何才能编写一个SessionBean,哪么我们就要来学习一下SessionBena的编程模型。
SessionBean规范:
|
|___Home接口 用来和远程容器进行通信
|
|___远程接口 封装了Bean类的业务方法,暴露在外方便调用
|
|___Bean类 封装了具体的业务代码实现
ejb-jar.xml (部署描述符)容器通过读取里面的配置信息,就知道哪些是会话Bean,哪些是实体Bena。还有他们的事务操作全部都定义在其中。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<display-name>EJBModule1</display-name>
<enterprise-beans>
<session>
<ejb-name>Converter</ejb-name>
<home>org.ejb.sessionbean.ConverterHome</home>
<remote>org.ejb.sessionbean.Converter</remote>
<ejb-class>org.ejb.sessionbean.ConverterBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</ejb-jar>
weblogic-ejb-jar.xml 这个是我选择J2EE是weblogic后产生的,里面主要配置了ejb的Bean类名称和JNDI的名称。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd">
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>Converter</ejb-name>
<jndi-name>Converter</jndi-name>
</weblogic-enterprise-bean>
<weblogic-enterprise-bean>
<ejb-name>Count</ejb-name>
<jndi-name>Count</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
介绍完规范后,我们来讲解一下SessionBean被客户端的调用过程:
现在我们就来按照EJB规范来编写SessionBean,我们这个SessionBean的名称叫Count用于计算次数。
首先我们要编写的是Home接口,注意命名要规范。
CountHome:
Public interface CountHome extends EJBHome{
//现在只是建立一个Home接口,它必须继承EJBHome
public Count create () throws CreateException,RemoteException;
//该方法告诉容器需要获得一个去创建Bean类一个实例并返回它的引用(及远程接口)
}
------------------------------
其次是远程接口,我们命名为Count:
public interface Count extends EJBObect{
//远程接口里面定义业务方法,它会抛出远程异常
public int getNumber() throws RemoteException;
}
-------------------------------
最后我们编写Bean类,命名为CountBean:
public class CountBean implements SessionBean{
SessionContext sessionContext;//上下文对象
//注意我们编写的SessionBean必须实现SessionBean这个接口
//这个接口里面定义了会话Bean的生命周期
public void ejbCreate() throws CreateException {}//创建对象,可能抛出创建异常
public void ejbRemove(){}//移出对象
public void ejbActivate(){}//激活对象
public void ejbPassivate(){}//钝化对象
public void setSessionContext(SessionContext sessionCount){
//在Bean类上设置上下文
this.sessionContext = sessionCount;//系统会调用并传入上下文对象与Bean类中的上下文对象匹配
}
int count = 0;//声明一个成员变量
//实际的业务代码实现
public int getNumber(){
System.out.println(count);
count = count +1;
return count;
}
}
编写完这三个Java文件后,我们还需要编写ejb-jar.xml文件,配置整个部署信息。
<ejb-jar>
<display-name>EJBModule1</display-name>
<enterprise-beans>
<session>
<ejb-name>Count</ejb-name>
<home>org.ejb.sessionbean.CountHome</home>
<remote>org.ejb.sessionbean.Count</remote>
<ejb-class>org.ejb.sessionbean.CountBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</ejb-jar>
然后编辑weblogic-ejb-jar.xml将ejb组件的名称和jndi进行绑定
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>Count</ejb-name>
<jndi-name>Count</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
使用JB编译后,生成一个*.ear文件。将这个文件部署到服务器上。如果没有异常则说明部署成功。
部署成功后,我们编写一个Client来测试EJB组件。
public class ConverterClient {
public ConverterClient() {}
public static void main(String[] args) {
/*第一部分--------------------------------*/
Properties properties = null;
try {
properties = new Properties();//配置文件
//声明初始化工厂类
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
//指定服务器通信地址
properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
//security_principal 安全_主要的(用户)
properties.put(Context.SECURITY_PRINCIPAL, "");
//security_credentials 安全_信任状(密码)
properties.put(Context.SECURITY_CREDENTIALS, "");
} catch (Exception e) {
System.out.println("设置环境异常");
}
/*第二部分------------------------------*/
ConverterHome home = null;
if(properties!=null){
try {
Context context = new InitialContext(properties);//初始化上下文
Object obj = context.lookup("Converter");//通过JNDI查找实例
try {//通过远程调用得到home对象(得到容器的骨架)
home = (ConverterHome) PortableRemoteObject.narrow(obj,
ConverterHome.class);
} catch (Exception ex1) {
System.out.println("得到远程引用异常");
ex1.printStackTrace(System.out);
}
} catch (NamingException ex) {
System.out.println("上下文异常");
ex.printStackTrace(System.out);
}
}
/*第三部分-----------------------------------------*/
Converter converter= null;
try {
converter = home.create();//通过home骨架得到Converter存根(引用)
converter.getHello("Hello world");
} catch (RemoteException ex2) {
ex2.printStackTrace(System.out);
} catch (CreateException ex2) {
ex2.printStackTrace(System.out);
}
}
有状态会话Bean,主要是保存的用户会话状态。一个有状态会话Bean实例对应一个用户。
那么我们首先来编写一个有状态的会话Bean。我们使用的开发工具为JBuilder2006,它开发EJB起来比较方便。EJB容器使用weblogic8.1中文版。
建立相应的EJB项目后,开打EJB Designer设计窗口。设计一个有状态会话Bean。