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("消息已经发送"); } }测试结果:
一个客户端发送一条消息可以传递给多个接收方。相当于多人聊天室。