消息驱动Bean

 开始JMS编程前,我们需要配置消息到达的目标地址Destination,因为只有目标地址存在了,我们才能发送消息到这个地址
  。由于每个应用服务器关于目标地址的配置都有所不同,下面以jboss为列。配置一个queue类型的目标地址。


<?xml version="1.0" encoding="UTF-8"?>
<server>
<mbean code="org.jboss.mq.server.jmx.Queue"
    name="jboss.mq.destinatio:service=Queue,name=firstQueue">
    <attribute name="JNDIName" >queue/firstQueue</attribute>
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
</server>

    jboss使用一個XML文件配置队列地址,文件的取名格式应遵守 "-service.xml
    <attribute name="JNDIName">属性指定了该目标地址的全局JNDI名称。如果你不指定
    JNDIName属性。jboss会为你生成一个默认的全局JNDI,其名称由' queue"+目标地址
   
    名称组成。
    另外在任何队列或主体被部署之前,应用服务器必须先部署Destination Manager Mbean .所以我们通过<depends>节点声明这一依赖。
   

先启动jboss 然后把这个文件发布到jboss-5.0.1.GA/server/default/deploy 下面

 

控制台下面就可以看到

15:53:51,937 INFO  [QueueService] Queue[queue/firstQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000

说明发布成功了


  
   一般发送消息有以下步骤:
   (1) 得到一个JNDI初始化上下文(Context)
   InitialContext ctx=new InitialContext();
    (2)根据上下文查找一个连接工厂 QueueConnectionFactory .该连接工厂是由JMS提供得,不需要我们自己创建,
    每个厂商都为他绑定了一个全局JNDI,我们通过它的全局JNDI便可获取它:
    QueueConnectionFactory factory=(QueueConnectionFactory)ctx.lookup("QueueConnectionFactory");

 

 

  注:如果此处 ctx.lookup("QueueConnectionFactory") 里面的QueueConnectionFactory 找不到 换成ConnectionFactory
    (3) 从连接工厂得到一个连接QueueConnection
       conn=factory.createQueueConnection();
      
    (4)通过连接来建立一个会话(Session)
    session=conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
     这句代码意思是:建立不需要事物的并且能自动确认消息已接受的会话。
    
    (5)查找目标地址
    例子对应代码
    Destination destination=(Destination)ctx.lookup("queue/firstQueue");
   
    (6)根据会话以及目标地址来建立消息生产者MessageProducer(QueueSender 和TopicPublisher都扩展自MessageProducer接口)
    例子对应代码:
    MessageProducer producer=session.createProducer(destination);
    TextMessage msg=session.createTextMessage("hello ,this is the first message driver bean");
    producer.send(msg);
   
    采用消息驱动Bean(Message Driven Bean)接收消息
   
    消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件,它和无状态Session Bean一样
    也使用了实例池技术,容器可以使用一定数量的bean实例并发处理成百上千个JMS消息。正
    因为MDB具有处理大量并发消息的能力,所以非常适合应用在一些消息网管产品,如果一个
    业务执行的时间很长,而执行结果无需实时向用户反馈时,也很适合使用MDB,如订单成功后
    给用户发送一封电子邮件或发送一条短信等。
    一个MDB 通常要实现MessageListener接口,该接口定义了onMessage()方法。Bean通过它来处理
    收到的JMS消息。
   
    package javax.jms:
    public interface MessageListener{
     public void onMessage(Message message);
    }
   
    当容器检测到Bean守候的目标地址有消息到达时,容器调用onMessage()方法,将消息作为参数
    传入MDB.MDB在onMessage()中决定如何处理该消息,你可以使用注释指定MDB监听哪一个
    目标地址(Destination).当MDB部署时,容器将读取其中的配置信息。
   
    

下面这个是发送消息

package com;

import java.util.Properties;

import javax.jms.BytesMessage;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

import com.foshanshop.ejb3.bean.Man;
/**
 * 发送Queue消息
 * @
 *
 */
public class QueueSender {
    public static void main(String[] args) {
        QueueConnection conn = null;
        QueueSession session = null;
        try {
            Properties props = new Properties();
            props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            props.setProperty(Context.PROVIDER_URL, "localhost:1099");
            props.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
           
            InitialContext ctx = new InitialContext(props);
            QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
            conn = factory.createQueueConnection();
            session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            Destination destination = (Queue) ctx.lookup("queue/firstQueue");
            MessageProducer producer = session.createProducer(destination);
           
            //发送文本
            TextMessage msg = session.createTextMessage("您好,这是我的第一个消息驱动Bean");
            producer.send(msg);
           
            //发送Ojbect(对象必须实现序列化,否则等着出错吧)
           // producer.send(session.createObjectMessage(new Man("劉德華", "北京朝阳区和平里一号")));
           
            //发送MapMessage
            MapMessage mapmsg = session.createMapMessage();
            mapmsg.setObject("no1", "北京和平里一号");
            producer.send(mapmsg);
           
            //发送BytesMessage
            BytesMessage bmsg = session.createBytesMessage();
            bmsg.writeBytes("我是一个兵,来自老百姓".getBytes());
            producer.send(bmsg);           
           
            //发送StreamMessage
            StreamMessage smsg = session.createStreamMessage();
            smsg.writeString("巴巴运动网,http://www.babasport.com");
            producer.send(smsg);
           
        } catch (Exception e) {
         e.printStackTrace();
        }finally{
            try {
                session.close ();
                conn.close();
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

 

然后需要编写消息驱动bean

 

 

package com;

import java.io.ByteArrayOutputStream;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.BytesMessage;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;

 

@MessageDriven(activationConfig =
{
  @ActivationConfigProperty(propertyName="destinationType",
    propertyValue="javax.jms.Queue"),
  @ActivationConfigProperty(propertyName="destination",
    propertyValue="queue/firstQueue"),
  @ActivationConfigProperty(propertyName="acknowledgeMode",
    propertyValue="Auto-acknowledge")
})

public class PrintBean implements MessageListener {

    public void onMessage(Message msg) {
        try {           
            if (msg instanceof TextMessage) {
                TextMessage tmsg = (TextMessage) msg;
                String content = tmsg.getText();
                System.out.println(content);
            }else if(msg instanceof MapMessage){
                MapMessage map = (MapMessage) msg;
                String content = map.getString("no1");
                System.out.println(content);
            }else if(msg instanceof BytesMessage){
                BytesMessage bmsg = (BytesMessage) msg;
                ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[256];
                int length = 0;
                while ((length = bmsg.readBytes(buffer)) != -1) {
                      byteStream.write(buffer, 0, length);
                }
                String content = new String(byteStream.toByteArray());
                byteStream.close();
                System.out.println(content);
            }else if(msg instanceof StreamMessage){
                StreamMessage smsg = (StreamMessage) msg;
                String content = smsg.readString();
                System.out.println(content);
            }
           
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

打成jar 包 发布到  jboss-5.0.1.GA/server/default/deploy 就可以看到刚才发送的消息 已经接收到了

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值