Java Message Service (JMS) служит для асинхронного взаимодействия компонентов системы. В JMS выделяется 3 участника:
1) отправитель сообщения (producer)
2) пункт назначения (destination, broker) - могут быть очередь (взаимодействие точка-точка) или топик (взаимодействие уведомление/подписчики)
3) получатель сообщения (consumer)
Отправитель посылает сообщение пункту назначения. Получатель сообщения читает из пункта назначения. Отправитель ничего не знает о получателе и не знает о времени прочтения, то есть отправитель и получатель не обязательно должны работать одновременно. Сообщения - любые объекты, поддерживающие сериализацию.
Примерный порядок работы в нетбинсе (для разных пунктов назначения работа одинаковая):
1) Для начала нужно создать пункт назначения и фабрику, которая создает пункт назначения. Это делается или в консоли управления сервером приложения (например глассфише) или путем добавления ресурса в нетбинсе (описание ресурсов добавляется в glassfish-resources.xml и при развертывании ресурсы создаются на сервере приложения).
2) Отправителя и получателя можно создать в одном энетрпрайз приложении (отправитель консольное приложение и получатель message driven бин).
3) В отправителе вызываем "Send JMS Message" и нетбинс добавляет весь код. Создаваемый код будет разный например для консольного клиента и клиента упраляемого бина. В первом случае будет создана классическая схема отправки сообщения, во втором упрощенная (более новая) с сипользованием инжекции JMSContext.
Пример для консольного клиента (классическая схема):
public class Main {
@Resource(mappedName = "jms/testQueue")
private static Queue testQueue;
@Resource(mappedName = "jms/testQueueFactory")
private static ConnectionFactory testQueueFactory;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
Main m = new Main();
for(int i = 0; i < 10000; i ++)
m.sendJMSMessageToTestQueue(Integer.toString(i));
} catch (JMSException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private Message createJMSMessageForjmsTestQueue(Session session, Object messageData) throws JMSException {
// TODO create and populate message to send
TextMessage tm = session.createTextMessage();
tm.setText(messageData.toString());
return tm;
}
private void sendJMSMessageToTestQueue(Object messageData) throws JMSException {
Connection connection = null;
Session session = null;
try {
connection = testQueueFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(testQueue);
messageProducer.send(createJMSMessageForjmsTestQueue(session, messageData));
} finally {
if (session != null) {
try {
session.close();
} catch (JMSException e) {
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot close session", e);
}
}
if (connection != null) {
connection.close();
}
}
}
}
Пример для упрощенной схемы:
@Resource(mappedName = "jms/testQueue")
private Queue testQueue;
@Inject
@JMSConnectionFactory("java:comp/DefaultJMSConnectionFactory")
private JMSContext context;
private void sendJMSMessageToTestQueue(String messageData) {
context.createProducer().send(testQueue, messageData);
}
Приемник сообщения может быть MDB бин. Его реализация примерно следующая:
import java.util.logging.Level;
import java.util.logging.Logger;
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 = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/testQueue")
})
public class testMessageBean implements MessageListener {
public testMessageBean() {
}
@Override
public void onMessage(Message message) {
try {
TextMessage tmess = (TextMessage)message;
System.err.println("Первый: " + tmess.getText());
} catch (JMSException ex) {
Logger.getLogger(testMessageBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
|