EJB3.0介绍系列二——消息bean与排队买票<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

       回来的这几周一直在弄Struts2.0Hibernate,所以把EJB3.0这个系列的搁置了一下,今天在写服务包的时候刚好又看到这个标题,所以将里面的一些内容挑了点,放在这里,希望和朋友们交流、学习。
       前面说了session bean的一种无状态会话bean,现在我在说EJB3.0里面的第二种bean,消息bean(即jms——Java Messaging Service后面也说driver manage bean)。上次的文章中,我说session bean是一种同步机制,但是在我们做项目开发的时候,大家都知道,不是说所有的操作都是同步的。这个时候我们就引出了第二种操作方式,异步交互。在这里我将个大家形象的解释一下什么是异步交互。比如说:朋友们都排队买过票吧,我们都知道,不是向同步那样到车站就直接能买到票,人多的情况下我们需要排队,我们要等前面的人买完了,到我了,我才能去买票。其实我们可以将这个场景看做是一个异步,我们排队的人可以看成消息队列,那么这个场景就是典型的先进先出式的消息队列。
       有了上面场景的认识我再给一个示意图:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
在上图中,我们就是那么发送器,我们要买票。售票员就是接收器,买票。而我们为买票排的队就是消息队列。
       好,有了上面的认识,下面我来说说在整个体系中消息bean所在的位置,如图:
这个图熟悉吗?session bean的文章也是用的这个图,我们看到,消息beansession 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