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

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

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

    隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
    數(shù)據(jù)加載中……

    eclipse + JBoss 5 + EJB3開發(fā)指南(14):消息驅(qū)動(dòng)Bean

    本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!

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

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

    一、實(shí)現(xiàn)實(shí)體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;
        }
        
    }

    二、編寫消息驅(qū)動(dòng)Bean

        消息驅(qū)動(dòng)Bean必須實(shí)現(xiàn)MessageListener接口,當(dāng)該消息驅(qū)動(dòng)Bean接收到一個(gè)消息后,EJB容器就會(huì)調(diào)用MessageListener接口的onMessage方法來(lái)理該消息。消息驅(qū)動(dòng)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對(duì)象!");
                }
                
    else
                {
                    System.out.println(
    "消息類型錯(cuò)誤!");
                }
            }
            
    catch (Exception e)
            {
                
    throw new EJBException(e);
            }

        }

    }

        消息驅(qū)動(dòng)Bean需要使用@MessageDriven進(jìn)行注釋。要注意的是destination屬性的值是queue/MDBQueue。JBoss不會(huì)自已建立一個(gè)Queue對(duì)象,因此,需要手工來(lái)配置Queue對(duì)象。讀者可以<JBoss5.x安裝目錄>\server\default\deploy目錄中建立一個(gè)xxx-service.xml文件,其中xxx可以任意取值,但必須跟“-service”后綴,例如,abc-service.xml。該文件可以放在deploy或其子目錄(可以是多層子目錄)中。該文件的內(nèi)容如下:
    <?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中的/后面的部分一致。如果不進(jìn)行上面的配置,在啟動(dòng)JBOSS時(shí)就會(huì)拋出如下的異常:

    javax.naming.NameNotFoundException: MDBQueue not bound


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

    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'
    ... ...
     

    三、編寫調(diào)用消息驅(qū)動(dòng)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(
    "成功發(fā)送消息!");
            }
            
    catch (Exception e)
            {
                System.out.println(
    "發(fā)送消息失敗!");
            }

            
    return "方法成功返回";

        }
    }

        在上面的代碼中使用ObjectMessage對(duì)象來(lái)包裝要向消息服務(wù)器發(fā)送的實(shí)體Bean的對(duì)象實(shí)例。
        除了可以在SessionBean中訪問消息驅(qū)動(dòng)Bean外,還可以在不同的機(jī)器上通過jndi來(lái)查找并調(diào)用消息驅(qū)動(dòng)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(
    "成功發(fā)送消息!");
        }
    }

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





    Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺(tái)灣)

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

    主站蜘蛛池模板: 毛片高清视频在线看免费观看| 色偷偷亚洲女人天堂观看欧| 日韩免费a级在线观看| 99re在线视频免费观看| aa午夜免费剧场| 美女羞羞视频免费网站| 亚洲中文字幕无码爆乳| 亚洲国产成人综合| 日韩精品一区二区亚洲AV观看| 亚洲精品视频免费观看| 在线免费一区二区| A级毛片内射免费视频| 2015日韩永久免费视频播放 | 久久免费美女视频| 九九综合VA免费看| 粉色视频成年免费人15次| 亚洲综合一区无码精品| 亚洲人成网站在线观看播放动漫| 亚洲国产国产综合一区首页| 亚洲区小说区激情区图片区| 国产成人精品日本亚洲专区 | 色婷婷精品免费视频| 国产亚洲欧美在线观看| 亚洲高清毛片一区二区| 中文字幕无码精品亚洲资源网久久| 亚洲成av人片在线看片| 亚洲国产精品久久久久秋霞影院 | 日韩精品在线免费观看| 黄色免费在线网站| 无码人妻一区二区三区免费n鬼沢 无码人妻一区二区三区免费看 | 日本免费污片中国特一级| 两个人看的www免费高清| 巨胸喷奶水www永久免费| 女人裸身j部免费视频无遮挡| 羞羞漫画登录页面免费| 一级做a爰片久久免费| 国产精品九九久久免费视频| 久久久久久噜噜精品免费直播| 中文字幕av无码不卡免费| 中文字幕乱码免费看电影| 无码精品人妻一区二区三区免费看 |