EJB3.0介绍系列二——消息bean与排队买票
回来的这几周一直在弄Struts2.0和Hibernate,所以把EJB3.0这个系列的搁置了一下,今天在写服务包的时候刚好又看到这个标题,所以将里面的一些内容挑了点,放在这里,希望和朋友们交流、学习。
前面说了session bean的一种无状态会话bean,现在我在说EJB3.0里面的第二种bean,消息bean(即jms——Java Messaging Service后面也说driver manage bean)。上次的文章中,我说session bean是一种同步机制,但是在我们做项目开发的时候,大家都知道,不是说所有的操作都是同步的。这个时候我们就引出了第二种操作方式,异步交互。在这里我将个大家形象的解释一下什么是异步交互。比如说:朋友们都排队买过票吧,我们都知道,不是向同步那样到车站就直接能买到票,人多的情况下我们需要排队,我们要等前面的人买完了,到我了,我才能去买票。其实我们可以将这个场景看做是一个异步,我们排队的人可以看成消息队列,那么这个场景就是典型的先进先出式的消息队列。
有了上面场景的认识我再给一个示意图:
在上图中,我们就是那么发送器,我们要买票。售票员就是接收器,买票。而我们为买票排的队就是消息队列。
好,有了上面的认识,下面我来说说在整个体系中消息bean所在的位置,如图:
这个图熟悉吗?session bean的文章也是用的这个图,我们看到,消息bean和session bean处在的地位也是平行的,所以消息的使用环境我们也就知道了,和session bean一样,何时使用是根据项目的需求和设计来的。
知道消息机制的原理和使用条件之后,我来说一个最最简单的例子,希望大家参考。
我们创建一个新对象,在EJB3.0那栏里:写上如下代码
package com;
import java.io.Serializable;
import java.util.Properties;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@MessageDriven
(activationConfig=
{
@ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination",propertyValue="queue/myqueue")
}
)
public class HelloQueueDriverBean implements MessageListener {
public void send(String StrMessage) throws NamingException, JMSException
{
try
{
Properties props=new Properties();
props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url","localhost:1099");
props.setProperty("java.naming.factory.url.pkgs","org.jboss.naming");
InitialContext context=new InitialContext(props); //获得QueueConnectionFactory对象
QueueConnectionFactory factory=(QueueConnectionFactory) context.lookup("ConnectionFactory"); //创建QueueConnection
QueueConnection connection=factory.createQueueConnection(); //创建QueueSession对象
QueueSession session=connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
//获取destination对象
Queue queue=(Queue) context.lookup("queue/myqueue");
//创建可序列化对象的消息
//ObjectMessage om = session.createObjectMessage(helloEntityBean);
//创建文本消息
TextMessage txt=session.createTextMessage(StrMessage);
//创建发送者
QueueSender sender=session.createSender(queue);
//发送消息
sender.send(txt);
//关闭会话
session.close();
connection.close();
}
catch(Exception ex)
{
output(ex.getMessage());
}
}
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message msg) {
// TODO Auto-generated method stub
try
{
TextMessage tm=(TextMessage)msg;
HelloEntityBean heb = new HelloEntityBean();
heb.setName(tm.getText());
heb.setDescription(tm.getText()+ "Queue消息");
Boolean back = heb.add(heb);
}
catch (JMSException e)
{
e.printStackTrace();
}
}
仔细分析一下上面上面的代码,我们发现,其实Jms实现的步骤和我们排队买车票的步骤也是差不多的,我们向一个消息队列添加消息(即我们找一个卖票的队伍排好队),然后等待函数执行onMessage方法(就好像等待前面的人买票),前面的消息处理完时处理这个消息(即我们等前面人都买完票时我们到售票口买票)。呵呵,很好理解吧!有时间我在说消息bean的第二种方式,发布订阅消息bean。