<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

    主站蜘蛛池模板: 免费人成在线观看视频高潮| 日本免费人成在线网站| 亚洲AV美女一区二区三区| 中文免费观看视频网站| 国产成人 亚洲欧洲| 久久青青草原亚洲AV无码麻豆| 成人免费视频一区| 91成人免费福利网站在线| 亚洲精品免费网站| 亚洲乱码中文字幕综合| 成人免费视频一区二区三区| 青青青国产手机频在线免费观看 | 亚洲熟妇无码av另类vr影视| 亚洲成av人在片观看| 四虎成年永久免费网站| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 一级毛片正片免费视频手机看| 亚洲男人都懂得羞羞网站| 国产成人在线观看免费网站| 久久精品一本到99热免费| 国产精品亚洲综合天堂夜夜| 久久久无码精品亚洲日韩按摩| 无码国产亚洲日韩国精品视频一区二区三区 | 免费一级特黄特色大片| 亚洲校园春色另类激情| 亚洲国产精品特色大片观看完整版 | 性无码免费一区二区三区在线| 亚洲av成本人无码网站| 亚洲日本乱码一区二区在线二产线| 亚洲欧洲日产国码高潮αv| 91在线视频免费看| 久久狠狠躁免费观看2020| 在线播放国产不卡免费视频| 中文日韩亚洲欧美制服| 久久精品国产亚洲av麻豆色欲| 亚洲一区二区三区在线播放| 在线观看免费国产视频| 无码国产精品一区二区免费I6| 一级毛片在线免费观看| 欧洲人免费视频网站在线| 国产又黄又爽胸又大免费视频|