MessageDriven Bean是EJB2.0中引入的新的企业Bean,它基于JMS消息,只能接收客户端发送的JMS消息然后处理。对客户端来说,message-driven bean就是异步消息的消费者,当消息到达之后,由容器负责调用MDB。客户端发送消息到destination,MDB作为一个MessageListener接收消息。
JMS支持两种消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即点对点和发布订阅模型。
P2P:每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
Pub/sub:每个消息可以有多个消费者。
下面举例:
P2P
P2P消息传递模型规定了一条消息只能传递给一个接收方。采用javax.jms.Queue表示。为了证明客户端发的消息只能有一个消费者接收,建立两个EJB Project。
EJB Projec1:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/myqueue")
}
)
public class MyMDBBean implements MessageListener{
public void onMessage(Message msg) {
TextMessage textMessage=(TextMessage)msg;
try {
System.out.println("MyQueueMDBBean被调用了【"+textMessage.getText()+"】");
} catch (JMSException e) {
e.printStackTrace();
}
}
}
EJB Project2:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/myqueue")
}
)
public class MyMDBBean02 implements MessageListener{
public void onMessage(Message msg) {
TextMessage textMessage=(TextMessage)msg;
try {
System.out.println("MyQueueMDBBean02被调用了【"+textMessage.getText()+"】");
} catch (JMSException e) {
e.printStackTrace();
}
}
}
客户端测试类:
public class MyQBeanClient {
/**
* 消息驱动Bean客户端 (点对点模式)
* @param @param args
*/
public static void main(String[] args)throws Exception {
InitialContext ctx = new InitialContext();
//获取ConnectionFactory
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("ConnectionFactory");
//创建QueueConnection对象
QueueConnection connection = factory.createQueueConnection();
//创建QueueSession对象,第一个参数表示事务自动提交,第二个参数标识一旦消息被正确送达,将自动发回响应
QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
//获取Destination对象
Queue queue = (Queue)ctx.lookup("queue/myqueue");
//创建文本消息
TextMessage msg = session.createTextMessage("世界,你好");
//创建发送者
QueueSender sender = session.createSender(queue);
//发送信息
sender.send(msg);
//关闭会话
session.close();
System.out.println("消息已经发送");
}
}
测试结果:
两个MDB,一个客户端发送消息只能有一个接受到,随机的。
Pub/sub
Pub/sub消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示。也同样建立两个EJB Project。
EJB Project1:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"),
@ActivationConfigProperty(propertyName="destination", propertyValue="topic/myTopic")
}
)
public class MyTopicMDBBean implements MessageListener{
public void onMessage(Message msg) {
TextMessage textMessage=(TextMessage)msg;
try {
System.out.println("MyTopicMDBBean被调用了【"+textMessage.getText()+"】");
} catch (JMSException e) {
e.printStackTrace();
}
}
}
EJB Project2同上。
客户端测试类:
public class MyTopicBeanClient {
/**
* 消息驱动Bean客户端 (pub/subm模式)
* @param @param args
*/
public static void main(String[] args)throws Exception {
InitialContext ctx = new InitialContext();
//获取ConnectionFactory
TopicConnectionFactory factory = (TopicConnectionFactory)ctx.lookup("ConnectionFactory");
//创建TopicConnection对象
TopicConnection connection = factory.createTopicConnection();
//创建TopicSession对象,第一个参数表示事务自动提交,第二个参数标识一旦消息被正确送达,将自动发回响应
TopicSession session = connection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);
//获取Destination对象
Topic Topic = (Topic)ctx.lookup("topic/myTopic");
//创建文本消息
TextMessage msg = session.createTextMessage("世界,你好");
//创建发送者
TopicPublisher topicPublisher = session.createPublisher(Topic);
//发送信息
topicPublisher.publish(msg);
//关闭会话
session.close();
System.out.println("消息已经发送");
}
}
测试结果:
一个客户端发送一条消息可以传递给多个接收方。相当于多人聊天室。