<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    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 銀河使者 閱讀(2478) 評論(0)  編輯  收藏 所屬分類: java 原創ejb3JBoss

    主站蜘蛛池模板: a级毛片免费高清视频| 久久亚洲中文无码咪咪爱| 国产日韩AV免费无码一区二区三区| 免费精品一区二区三区在线观看| 亚洲国产高清在线精品一区| 222www免费视频| 亚洲色图视频在线观看| 无码日韩精品一区二区免费暖暖| 亚洲av鲁丝一区二区三区| 男人的天堂网免费网站| 久久久久亚洲AV无码专区首JN| 巨波霸乳在线永久免费视频 | 9420免费高清在线视频| 久久精品国产亚洲AV电影| 亚洲精品在线免费看| 午夜在线a亚洲v天堂网2019| 在线免费观看a级片| 国产精品亚洲一区二区在线观看| 日韩亚洲精品福利| 美女网站在线观看视频免费的 | 成年人在线免费看视频| 在线观看亚洲网站| 久久久久亚洲精品天堂久久久久久| 岛国精品一区免费视频在线观看| 久久精品国产亚洲麻豆| 亚欧在线精品免费观看一区| 亚洲精品欧美综合四区 | 亚洲成a人片在线观看中文动漫| 88av免费观看入口在线| 亚洲人成色4444在线观看| 久久久久亚洲AV综合波多野结衣 | 亚洲精华国产精华精华液好用 | 亚洲国产精品成人综合色在线| 亚洲日韩VA无码中文字幕| 一级毛片**不卡免费播| 亚洲日韩精品国产3区| 国产亚洲精品久久久久秋霞| 99久久国产热无码精品免费| 黄色大片免费网站| 久久精品国产亚洲AV嫖农村妇女| 国产美女精品久久久久久久免费|