EJB规范中定义了三种Bean,他们分别是会话Bean(Session Bean),实体Bean(Entity Bean),消息驱动Bean(MessageDrive Bean)。这三种Bean各自有各自的特点,并且他们分别应用于不同的情况,下面我们将就这三种Bean进行介绍。
1. 会话Bean。一个会话bean表示的是应用服务器中的单个客户程序,它被用来实现一个具有特定客户业务逻辑的事务对象。我们可以简单的理解为一个会话Bean完成一个用户功能。也正是因为多个用户可能在相同的时间执行相同的功能,并且每个用户执行相同功能后所返回的结果可能是不一样的,所以每个会话Bean只能特定的属于一个客户程序,但是会话Bean不是持久的,当一个客户程序终止的时候,会话Bean的生命周期就结束了,与客户程序再无关联。会话Bean有根据是否为特定的客户程序保存状态分为有状态的会话Bean和无状态的会话Bean。
实例:import javax.ejb.Stateless.*;
/**
* 一个简单无状态会话Bean实现了CalculateEJB接口的incrementValue()方法
**/
@Stateless(name="CalculateEJB")
public class CalculateEJBBean
implements CalculateEJB
{
int value = 0;
public String incrementValue()
{
value++;
return "value incremented by 1";
}
}
1. 实体Bean是可以存储在持久存储介质上的持久对象。实体Bean常用来表示永久性数据并提供操作这些数据的方法。一般情况下一个实体Bean对应着数据库中的一张表,而一个实体类的实例对应着这张表中的一条记录。实体Bean和会话Bean的最大区别在于实体Bean具有持久性,允许共享访问和主键的特性。实体Bean的状态保存在数据库中,可以被多个客户程序共享,每个实体Bean都有一个成为主键的唯一对象标识。
实例:
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
@Entity
@Table(name = "EMPLOYEES")
public class Employee implements java.io.Serializable
{
private int empId;
private String eName;
private double sal;
@Id
@Column(name="EMPNO", primaryKey=true)
public int getEmpId()
{
return empId;
}
public void setEmpId(int empId)
{
this.empId = empId;
}
public String getEname()
{
return eName;
}
public void setEname(String eName)
{
this.eName = eName;
}
public double getSal()
{
return sal;
}
public void setSal(double sal)
{
this.sal = sal;
}
public String toString()
{
StringBuffer buf = new StringBuffer();
buf.append("Class:")
.append(this.getClass().getName()).append(" :: ").append(" empId:").append(getEmpId()).append(" ename:").append(getEname()).append("sal:").append(getSal());
return buf.toString();
}
}
3. 消息驱动Bean。消息驱动Bean允许J2EE应用程序异步的接收Java消息服务(JMS)的消息。消息驱动Bean包含处理接受到的消息的事务逻辑,主要作用是处理消息。它与其他Bean(实体Bean和会话Bean)的区别主要在于以下几点:
a) 消息驱动Bean没有任何接口,客户程序不是通过接口来访问消息驱动Bean的,它处理的消息可以来自任何消息客户程序。
b) 消息驱动Bean类似于无状态会话Bean,是没有状态的,它的实例不保持特定客户程序的会话状态。
c) 消息驱动Bean不需要返回任何数值给他的客户程序,也不能向客户程序返回异常,因为消息驱动Bean是异步地处理消息的。
实例:
import javax.ejb.MessageDriven;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.Inject;
import javax.jms.*;
import java.util.*;
import javax.ejb.TimedObject;
import javax.ejb.Timer;
import javax.ejb.TimerService;
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"),
@ActivationConfigProperty(propertyName="destinationName", propertyValue="jms/myTopic"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'")
}
)
/**
*监听可配置JMS队列或者主题和通过当一个消息发送到队列或者主题
*调用它的onMessage()方法得到提醒的一个简单的消息驱动
*该Bean打印消息的内容
*/
public class MessageLogger implements MessageListener, TimedObject
{
@Inject javax.ejb.MessageDrivenContext mc;
public void onMessage(Message message)
{
System.out.println("onMessage() - " + message);
try
{
String subject = message.getStringProperty("subject");
String inmessage = message.getStringProperty("message");
System.out.println("Message received\n\tDate: " + new java.util.Date() + "\n\tSubject: " + subject + "\n\tMessage: " + inmessage + "\n");
System.out.println("Creating Timer a single event timer");
TimerService ts = mc.getTimerService();
Timer timer = ts.createTimer(30000, subject);
System.out.println("Timer created by MDB at: " + new Date(System.currentTimeMillis()) +" with info: "+subject);
}
catch (Throwable ex)
{
ex.printStackTrace();
}
}
public void ejbTimeout(Timer timer)
{
System.out.println("EJB 3.0: Timer with MDB");
System.out.println("ejbTimeout() called at: " + new Date(System.currentTimeMillis()));
return;
}
}
EJB 客户端实例:
import javax.naming.Context;
import javax.naming.InitialContext;
/**
* 一个调用无状态会话Bean中方法的简单的Bean客户端
*/
public class CalculateejbClient
{
public static void main(String [] args)
{
Context context = new InitialContext();
CalculateEJB myejb =
(CalculateEJB)context.lookup("java:comp/env/ejb/CalculateEJB");
myejb.incrementValue();
}
}
该贴由koei123转至本版2015-7-26 22:55:00