我的项目是基于websphere 8.5构建的,我们决定在项目中使用JMS quque作为消息。
所以,我创建了一个名为MyBus的总线,也创建了一个目标myBusDistination。
然后我创建了一个名为myConF的连接工厂
然后我创建了两个JMS队列,一个是带有JNDI jndi / myQueue1的myQueue1。另一个是带有JNDI jndi / mQueue2的myQueue2。
然后我创建了两个激活规范,一个是带有JNDI jndi / myAS1的myAS1,另一个是带有JNDI jndi / myAS2的myAS2。
然后我创建了两个消息驱动的bean,它们在EJB3.0中,名为MyMDB1和MyMDB2。 类代码就像这样,
@MessageDriven(mappedName = "jndi/myQueue1", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
public class MyMDB1 implements MessageListener {
@Override
public void onMessage(Message message) {
}
}
ejb_jar.xml就像这样,
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http:/java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0" metadata-complete="false">
<display-name>My MDB</display-name>
<enterprise-beans>
<message-driven>
<display-name>MyMDB1</display-name>
<ejb-name>MyMDB1</ejb-name>
<ejb-class>com.test.mdb.MyMDB1</ejb-class>
<message-destination-ref>
<message-destination-ref-name>jndi/myQueue1</message-destination-ref-name>
<message-destination-type>javax.jms.Queue</message-destination-type>
<message-destination-usage>Consumes</message-destination-usage>
<message-destination-link>jndi/myQueue1</message-destination-link>
</message-destination-ref>
</message-driven>
<message-driven>
<display-name>MyMDB2</display-name>
<ejb-name>MyMDB2</ejb-name>
<ejb-class>com.test.mdb.MyMDB2</ejb-class>
<message-destination-ref>
<message-destination-ref-name>jndi/myQueue2</message-destination-ref-name>
<message-destination-type>javax.jms.Queue</message-destination-type>
<message-destination-usage>Consumes</message-destination-usage>
<message-destination-link>jndi/myQueue2</message-destination-link>
</message-destination-ref>
</message-driven>
</enterprise-beans>
ibm-ejb-jar-bnd.xml就像这样,
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"
version="1.0">
<message-driven name="MyMDB1">
<jca-adapter activation-spec-binding-name="jndi/myAS1" destination-binding-name="jndi/myQueue1"/>
<message-destination-ref name="jndi/myQueue1" binding-name="jndi/myQueue1" />
</message-driven>
<message-driven name="MyMDB2">
<jca-adapter activation-spec-binding-name="jndi/myAS2" destination-binding-name="jndi/myQueue2"/>
<message-destination-ref name="jndi/myQueue2" binding-name="jndi/myQueue2" />
</message-driven>
最后,这是我测试的代码,
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"com.ibm.websphere.naming.WsnInitialContextFactory");
props.put(Context.PROVIDER_URL, "corbaloc:iiop:localhost:2809"); InitialContext ctx = new InitialContext(props);
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF");
Destination destination = (Destination) ctx.lookup("jndi/myQueue1");
Connection conn = factory.createConnection();
Session session = conn.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
ObjectMessage objMsg = session.createObjectMessage();
objMsg.setObject("MDB Test");
producer.send(objMsg);
session.close();
conn.close();
奇怪的是,
可以发送消息,MDB MyMDB1可以处理消息(如果我在MyMDB1.onMesssage()中记录了某些内容)。但是,如果我再次发送消息。该消息将由MyMDB2处理。
任何人对这个“奇怪的事情”都有一些想法吗?
答案 0 :(得分:1)
据我了解,您创建了两个连接到同一目标的JMS队列(jndi / myQueue1,jndi / myQueue2)。这就是为什么两个MDB都在等待来自该目的地的消息。结果,哪一个从队列中获取消息将更快运行。这是一种不好的做法。 在您的测试中,您只使用jndi / myQueue1和jndi / myAS1将消息放入目标,但这并不意味着。 您可以尝试停止其中一个MDB,然后您可以看到它只能用于另一个MDB,并且消息不会保留在队列中。
更新。如果需要两个不同的队列来接收不同的消息。你应该做这样的事情:
myDestination2
。myQueue2
(资源 - &gt; JMS-&gt;队列)的配置。在“连接”栏中,将“队列名称”从myBusDistination
更改为myDestination2
。要为第二个MDB使用消息:
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF");
Destination destination = (Destination) ctx.lookup("jndi/myQueue2");
将消息放到第一个没有任何变化:
ConnectionFactory factory = (ConnectionFactory) ctx.lookup("jndi/myConF");
Destination destination = (Destination) ctx.lookup("jndi/myQueue1");
答案 1 :(得分:0)
您必须为每个队列创建一个总线目标,因此,myBusDistination1
queue1
和myBusDistination2
queue2
。然后,当您发送到queue1时,MDB1将收到该消息,如果您将发送到queue2,MDB2将收到该消息。如果您希望所有MDB都收到相同的消息,则必须创建topic
而不是队列,以及指向该主题的激活规范。
您没有在问题中指明您实际想要实现的目标。