1、说明:EJB提供了基于jms的消息驱动bean(MDB),来处理消息服务的业务bean。比如我们在jd网上买东西,确认订单后会想服务器发送一消息(订单生成),但是在服务器处理该消息是异步的,客户端不必等待服务器的处理结果。这里只是打个比方,易于大家理解。
2.进入正题:ejb3.0消息驱动bean主要有两种:一种是基于发布/订阅(pub/sub);第二种是基于点对点(PTP)。
a.发布/订阅的特点是消息的生产者(也称消息的发布者)可以是多个,消费者也是多个,如下图:
b.点对点的特点是生产者可以多个单消费者只有一个,如下图:
3.下面我们开发一个基于Queue的点对点消息驱动bean
a.首先我们创建一个Ejb项目
b.我们要在jboss配置好jndi信息jboss-5.1.0.GA\server\default\deploy/queue-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: mail-service.xml 62350 2007-04-15 16:50:12Z dimitris@jboss.org $ -->
<server>
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.org.destination:server=Queue,name=myQueue" >
<attribute name="JNDIName" >queue/myQueue</attribute>
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
</server>
c.开发消息的生产者
package com.ejb.mdb;
import java.util.Properties;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
public class MsgProduct {
/**
* @param args
*/
public static void main(String[] args) {
QueueConnection qconn = null;
QueueSession qsession = null;
//上下文信息
Properties props = new Properties();
props.setProperty("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs",
"org.jboss.naming:org.jnp.interfaces");
try {
/*初始化jndi*/
InitialContext ctx = new InitialContext(props);
/*查找链接工厂*/
QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
/*使用链接工厂创建jms链接*/
qconn = factory.createQueueConnection();
/*使用jms创建session*/
qsession = qconn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
/*查找目的地*/
Destination destioation = (Destination) ctx.lookup("queue/myQueue");
/*创建消息生产者*/
MessageProducer producer = qsession.createProducer(destioation);
/*创建和发布消息*/
TextMessage textMessage = qsession.createTextMessage("hello mdb!");
producer.send(textMessage);
/*打印信息*/
System.out.println("jms消息已发出!");
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
/*关闭资源*/
qsession.close();
qconn.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
d.消息的消费者
package com.ejb.mdb;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(activationConfig = {
/**
* 设定MDB所监听消息目的的类型
*/
@ActivationConfigProperty(propertyName="destinationType"
,propertyValue="javax.jms.Queue"),//队列类型
@ActivationConfigProperty(propertyName="acknowledgeMode"
,propertyValue="Auto-acknowledge"),
/**
* 设定MDB所监听消息目的的JNDI绑定名
*/
@ActivationConfigProperty(propertyName="destination"
,propertyValue="queue/myQueue")
},
/**
* 指定MDB所监听的消息目的的JNDI绑定名
*/
mappedName="MessageQueue"
)
public class MsgCustomer implements MessageListener {
public void onMessage(Message msg) {
if(msg instanceof TextMessage){
TextMessage txt = (TextMessage) msg;
try {
String context = txt.getText();
System.out.println("JMS消息为" + context);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
4.然后运行一下生产这,看看控制台的答应结果吧。
(在此处写的是基于queue队列的消息驱动bean,下节将会介绍Topic的消息驱动bean,敬请关注,大家若有疑问请email:zhenlai2011@hotmail.com)