我需要制作一个简单的消息驱动Bean,它将侦听动态添加的队列位置。我尝试了几种方法来实现这一点,但没有一种有效。我有一个使用esb和java消息队列的应用程序,并且我正在尝试在运行时从配置文件中读取队列位置,从而告诉我的消息驱动bean要侦听的队列是什么。我也不确定这是否可能。
我也尝试实现消息监听器,但因为我必须使用ejb模块,而ejb模块不支持主方法,它需要自己的容器(如消息驱动bean),我不知道用什么代替主方法来实现同样的目标。我不能使用会话bean,因为我需要实现客户机和服务之间的异步通信。
我也尝试过使用客户端应用程序(虽然它不是选项之一),但是maven项目不支持netbeans中这种类型的应用程序的调试和运行功能。
有谁知道这个问题的解决办法,或者至少有一些想法吗?这可能不是最好的解决方案,但是可以用有状态会话Bean异步地接收和处理JMS消息,这样做:
package com.example.statefuljms;
import javax.annotation.Resource;
import javax.ejb.Local;
import javax.ejb.Stateful;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@Stateful
@Local(MessageReceiverLocal.class)
public class MessageReceiver implements MessageReceiverLocal, MessageListener {
@Resource(mappedName = "ConnectionFactory")
private ConnectionFactory connectionFactory;
private QueueConnection connection;
@Override
public void start(String queueName) throws JMSException, NamingException {
Context initialContext = new InitialContext();
connection = (QueueConnection) connectionFactory.createConnection();
QueueSession session = (QueueSession) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) initialContext.lookup(queueName);
QueueReceiver receiver = session.createReceiver(queue);
receiver.setMessageListener(this);
connection.start();
}
@Remove
@Override
public void stop() throws JMSException {
connection.stop();
connection.close();
}
@Override
public void onMessage(Message message) {
// handle message here
}
}
使用Singleton来测试:
package com.example.statefuljms;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.jms.JMSException;
import javax.naming.NamingException;
@Startup
@Singleton
public class Test {
@EJB
private MessageReceiverLocal messageReceiver;
@PostConstruct
public void run() {
messageReceiver.start("/queue/myQueue");
}
@PreDestroy
public void cleanup() {
messageReceiver.stop();
}
}