隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0

          導航

          <2009年6月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          公告

          關注我的新浪微博

          我的著作









          常用鏈接

          留言簿(126)

          我參與的團隊

          隨筆分類(818)

          隨筆檔案(310)

          文章分類(1)

          文章檔案(8)

          相冊

          ADSL、3G查詢

          CSDN

          eclipse

          ibm

          Java EE

          Linux

          Web

          云服務

          代理網站

          關注的網站

          協議

          喜歡的Blog

          國內廣告平臺

          圖書出版

          在線培訓

          開發工具

          微博客戶端

          手機鈴聲

          操作系統

          • ReactOS
          • 一個與windowXP/2003兼容的操作系統

          數學

          文件格式

          源碼資源

          移動(Mobile)

          編程語言

          英語學習

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 1973524
          • 排名 - 6

          最新評論

          閱讀排行榜

          評論排行榜

          eclipse + JBoss 5 + EJB3開發指南(14):消息驅動Bean

          本文為原創,如需轉載,請注明作者和出處,謝謝!

          上一篇:eclipse + JBoss 5 + EJB3開發指南(13):在Servlet中訪問應用程序管制EntityManager對象

              在前面的文章中給出的SessionBean的例子都是同步調用SessionBean方法的,也就是說,只有當方法中的代碼都執行完,才能返回到客戶端。但在某些情況下,由于SessionBean方法的執行時間比較長,這就需要異步地調用該方法,否則客戶端就需要等待比較長的時間。要實現異步調用,就需要使用本要講的消息驅動Bean。消息驅動Bean的基本原理是客戶端向消息服務器發送一條消息后,消息服務器會將該消息保存在消息隊列中。在這時消息服務器中的某個消費者(讀取并處理消息的對象)會讀取該消息,并進行處理。發送消息的客戶端被稱為消息生產者。
              本文給出的消息驅動Bean的例子的基本功能是客戶端向消息服務器發送一條消息(該消息實際上是一個實體Bean的對象實例),然后消息消費者讀取這條消息后,將消息中的實體Bean持久化。實現消息驅動Bean的步驟如下:

          一、實現實體Bean

          package entity;

          import java.io.Serializable;
          import java.util.Date;
          import javax.persistence.Column;
          import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.GenerationType;
          import javax.persistence.Id;
          import javax.persistence.Table;

          @Entity
          @Table(name
          ="t_date")
          public class DateBean implements Serializable
          {
              
          private int id;
              
          private Date myDate;
              @Id
              @GeneratedValue(strategy
          =GenerationType.IDENTITY)
              
          public int getId()
              {
                  
          return id;
              }
              
              
          public void setId(int id)
              {
                  
          this.id = id;
              }
              @Column(name
          ="mydate")
              
          public Date getMyDate()
              {
                  
          return myDate;
              }
              
          public void setMyDate(Date myDate)
              {
                  
          this.myDate = myDate;
              }
              
          }

          二、編寫消息驅動Bean

              消息驅動Bean必須實現MessageListener接口,當該消息驅動Bean接收到一個消息后,EJB容器就會調用MessageListener接口的onMessage方法來理該消息。消息驅動Bean的代碼如下:

          package service;

          import javax.ejb.ActivationConfigProperty;
          import javax.ejb.EJBException;
          import javax.ejb.MessageDriven;
          import javax.jms.Message;
          import javax.jms.MessageListener;
          import javax.jms.ObjectMessage;
          import javax.persistence.EntityManager;
          import javax.persistence.PersistenceContext;
          import entity.DateBean;

          @MessageDriven( activationConfig 
          =  {        
                  @ActivationConfigProperty(propertyName 
          = "destinationType", propertyValue = "javax.jms.Queue"),
                  @ActivationConfigProperty(propertyName 
          = "destination", propertyValue = "queue/MDBQueue")
                })

          public class DateMessageBean implements MessageListener
          {
              @PersistenceContext(unitName 
          = "myentity1")
              
          private EntityManager em;

              @Override
              
          public void onMessage(Message message)
              {
                  
          try
                  {
                      
          if(message instanceof ObjectMessage)
                      {

                          ObjectMessage objmsg 
          = (ObjectMessage) message;
                          DateBean dateBean 
          = (DateBean) objmsg.getObject();
                          em.persist(dateBean);
                          System.out.println(
          "成功持久化DateBean對象!");
                      }
                      
          else
                      {
                          System.out.println(
          "消息類型錯誤!");
                      }
                  }
                  
          catch (Exception e)
                  {
                      
          throw new EJBException(e);
                  }

              }

          }

              消息驅動Bean需要使用@MessageDriven進行注釋。要注意的是destination屬性的值是queue/MDBQueue。JBoss不會自已建立一個Queue對象,因此,需要手工來配置Queue對象。讀者可以<JBoss5.x安裝目錄>\server\default\deploy目錄中建立一個xxx-service.xml文件,其中xxx可以任意取值,但必須跟“-service”后綴,例如,abc-service.xml。該文件可以放在deploy或其子目錄(可以是多層子目錄)中。該文件的內容如下:
          <?xml version="1.0" encoding="UTF-8"?>
          <server>
            
          <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=MDBQueue">
              
          <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
            
          </mbean>
          </server>

              要注意的是,<mbean>元素的name屬性值中的name必須是MDBQueue,要與queue/MDBQueue中的/后面的部分一致。如果不進行上面的配置,在啟動JBOSS時就會拋出如下的異常:

          javax.naming.NameNotFoundException: MDBQueue not bound


              也可以將<mbean>元素放在deploy目錄中的其他以-service.xml結尾的文件中。
              如果不設置destination屬性的值,在啟動JBoss是會拋出如下的異常:

          org.jboss.deployers.spi.DeploymentException: Required config property RequiredConfigPropertyMetaData@174098f[name=destination descriptions=[DescriptionMetaData@4ca30b[language=zh]]] for messagingType 'javax.jms.MessageListener' not found in activation config [ActivationConfigProperty(destinationType=javax.jms.Queue), ActivationConfigProperty(connectionFactoryJndiName=MyQueueConnectionFactory), ActivationConfigProperty(destinationName=MyRequestQueue)] ra=jboss.jca:service=RARDeployment,name='jms-ra.rar'
          ... ...
           

          三、編寫調用消息驅動Bean的SessionBean

          package service;

          import java.util.ArrayList;
          import java.util.Date;
          import java.util.List;
          import javax.annotation.Resource;
          import javax.ejb.Stateless;
          import javax.jms.Connection;
          import javax.jms.ConnectionFactory;
          import javax.jms.MessageProducer;
          import javax.jms.ObjectMessage;
          import javax.jms.Queue;
          import javax.jms.Session;
          import javax.persistence.EntityManager;
          import entity.DateBean;
          import entity.Greeting;

          @Stateless
          public class GreeterBean implements Greeter
          {
              @Resource(mappedName = "ConnectionFactory")
              
          private ConnectionFactory cf;
              @Resource(mappedName 
          = "queue/MDBQueue")
              
          private Queue queue;

              @Override
              
          public String greet(String message)
              {
                  try
                  {
                      DateBean db 
          = new DateBean();
                      db.setMyDate(
          new Date());
                      Connection connection 
          = cf.createConnection();
                      Session session 
          = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                      MessageProducer messageProducer 
          = session.createProducer(queue);
                      ObjectMessage objectMessage 
          = session.createObjectMessage();
                      objectMessage.setObject(db);
                      messageProducer.send(objectMessage);
                      connection.close();
                      System.out.println(
          "成功發送消息!");
                  }
                  
          catch (Exception e)
                  {
                      System.out.println(
          "發送消息失敗!");
                  }

                  
          return "方法成功返回";

              }
          }

              在上面的代碼中使用ObjectMessage對象來包裝要向消息服務器發送的實體Bean的對象實例。
              除了可以在SessionBean中訪問消息驅動Bean外,還可以在不同的機器上通過jndi來查找并調用消息驅動Bean,代碼如下:
          package test;

          import java.util.Date;
          import javax.ejb.EJB;
          import javax.jms.Destination;
          import javax.jms.MessageProducer;
          import javax.jms.ObjectMessage;
          import javax.jms.Queue;
          import javax.jms.QueueConnection;
          import javax.jms.QueueConnectionFactory;
          import javax.jms.QueueSession;
          import javax.jms.TextMessage;
          import javax.naming.InitialContext;
          import entity.DateBean;

          import service.Greeter;

          public class Client
          {

              public static void main(String[] args) throws Exception
              {
                  InitialContext ctx = new InitialContext();
                  QueueConnection connection 
          = null;
                  QueueSession session 
          = null;
                  QueueConnectionFactory factory 
          = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
                  connection 
          = factory.createQueueConnection();
                  session 
          = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
                  Destination destination 
          = (Queue) ctx.lookup("queue/MDBQueue");
                  MessageProducer messageProducer 
          = session.createProducer(destination);
                  ObjectMessage objectMessage 
          = session.createObjectMessage();
                  DateBean db 
          = new DateBean();
                  db.setMyDate(
          new Date());
                  objectMessage.setObject(db);
                  messageProducer.send(objectMessage);
                  connection.close();
                  System.out.println(
          "成功發送消息!");
              }
          }

          下一篇:eclipse + JBoss 5 + EJB3開發指南(15):攔截器方法和攔截器類





          Android開發完全講義(第2版)(本書版權已輸出到臺灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2009-06-08 23:40 銀河使者 閱讀(2484) 評論(0)  編輯  收藏 所屬分類: java 原創ejb3JBoss

          主站蜘蛛池模板: 龙川县| 宝兴县| 嘉义市| 高邮市| 绍兴县| 社会| 内江市| 张北县| 东山县| 沛县| 鄱阳县| 微山县| 溆浦县| 武陟县| 成都市| 余庆县| 农安县| 榆树市| 邢台县| 奇台县| 武强县| 九寨沟县| 特克斯县| 宾阳县| 葵青区| 喜德县| 金坛市| 苗栗市| 清新县| 新郑市| 朔州市| 营山县| 平阳县| 吉木乃县| 伊川县| 安仁县| 弥勒县| 普兰县| 屏东县| 油尖旺区| 金湖县|