(1)在JBoss中建一个Queue或Topic(Queue就是一个信息只有一个MDB接收,即使它有多个实例,Topic就是广播了,所有MDB都收到一份(每种MDB收到一份吧),发信的话自然用Queue了。),可以直接在jbossmq-destinations-service.xml中添加,里面有现成的,copy一个,改个名字就行了。比如是phoneQueue。
这样建立的Queue是永久Queue,是用数据库保存信息的,万一死机停电什么的,重启后信息还在。
如果不这样建立的话,启动时找不到指定名字的Queue,会自动建立一个临时的Queue,Server关掉的时候就没了。
(2)当然就写MDB了。大概样子如下:
package com.mkl.message;
import javax.jms.*; import javax.ejb.MessageDriven; import javax.ejb.ActivationConfigProperty;
@MessageDriven(name="PhoneMessageBean", activationConfig = { @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination", propertyValue="queue/phoneQueue") }) public class Phone implements MessageListener {
@Override public void onMessage(Message msg) { TextMessage textMsg = (TextMessage) msg; try { System.out.println("Received Phone Call:" + textMsg.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
EJB3.0里,只要实现MessageListener接口就行了,就一个onMessage方法。 注意的就是@MessageDriven注解的写法。
MDB就是无状态的,Server有个MDB池,一个MDB可能有多个实例在池里, 从而可以处理批量的信息,这个池是Server管理的。
queue/phoneQueue就是phoneQueue的JNDI查找名,Topic的话前缀是topic。
可能没有javax.jms的类,把jboss-j2ee.jar引到工程里就行了,这个jar在server/all/lib/下。
到此,部署一下,启动Server的时候,MDB就应该可以生效了。
(3)为了方便调用,将MDB变成一个组件。在components.xml 中
<component name="phoneQueueSender" class="org.jboss.seam.jms.ManagedQueueSender"> <property name="queueJndiName">queue/phoneQueue</property> </component>
也可以这样写:
<jms:managed-queue-sender name="phoneQueueSender" auto-create="true" queue-jndi-name="queue/phoneQueue"/>
jms前缀可能不认,上面得加: ------------------------- <components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:persistence="http://jboss.com/products/seam/persistence" xmlns:drools="http://jboss.com/products/seam/drools" xmlns:bpm="http://jboss.com/products/seam/bpm" xmlns:security="http://jboss.com/products/seam/security" xmlns:mail="http://jboss.com/products/seam/mail" xmlns:jms="http://jboss.com/products/seam/jms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.0.xsd http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.0.xsd http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.0.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.0.xsd http://jboss.com/products/seam/jms http://jboss.com/products/seam/jms-2.0.xsd http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd"> ------------------------------- 这样弄完以后,MDB就是组件了。
(4)就是使用了,往Queue里发信就行了,剩下就是MDB的工作了,咱就不管啦。
直接注入进来,queueSession是内置的组件,不需要配置,使用起来真方便,比纯EJB的要省不少代码。
反正就是千方百计把信息发送到Queue里,然后在MDB里把信息取出来,折腾折腾,发送出去就是了。
Message有TextMessage,ObjectMessate,StreamMessage,MapMessage...好几种。
@In(create=true) private transient QueueSender phoneQueueSender; @In(create=true) private transient QueueSession queueSession;
public void make_a_call (){ try { phoneQueueSender.send( queueSession.createTextMessage("You are in trouble")); } catch (Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } }
下面是Topic的写法:
@In private TopicPublisher stockTickerPublisher; @In private TopicSession topicSession;
public void publish(StockPrice price) { try { stockTickerPublisher.publish( topicSession.createObjectMessage(price) ); } catch (Exception ex){ throw new RuntimeException(ex); } }
================================== OK啦,什么ejb-jar.xml,jboss.xml都不管,就好使了……
|