Transcript 10-MDB

Message-Driven Beans
Василий Кряжев
[email protected]
Рассматриваемые темы
 Понятие обмена сообщениями
 Обзор Java Message Service
 Написание простых JMS клиентов
 Message-Driven Beans
1-2
Рассматриваемые темы
 Понятие обмена сообщениями
 Определение обмена сообщениями
 Message-oriented middleware (MOM)
 Обзор Java Message Service
 Написание простых JMS клиентов
 Message-Driven Beans
1-3
Обмен сообщениями (messaging)
Определение:
 Обмен сообщениями это механизм
который позволяет программам
взаимодействовать друг с другом
 Существует различные способы
обмена сообщениями, такие как:




TPC/IP sockets
Pipes
Files
Shared memory
1-4
Асинхронные сообщения
 Могут быть предпочтительнее
синхронного вызова методов, в
случае если метод ничего не
возвращает
 Позволяют лучше использовать
серверные ресурсы
1-5
Очереди сообщений
 Могут улучшить
производительность
 Позволяют задание приоритета
(сообщения с высоким
приоритетом обрабатываются
раньше)
1-6
Message-oriented middleware
Существует целый класс систем
(готовые инфраструктуры), которые
позволяют приложениям
взаимодействовать друг с другом, через
механизм обмена сообщений
1-7
Рассматриваемые темы
 Понятие обмена сообщениями
 Обзор Java Message Service
 Модель доставки Point-to-Point
 Модель доставки Publish/Subscribe
 Долговременные подписчики
 Написание простых JMS клиентов
 Message-Driven Beans
1-8
Java Message Service JMS
Java Message Service (JMS) это
стандартный API для доступа к
message-oriented middleware
(MOM).
1-9
Использование JMS
Выгоды при использовании JMS:
см. далее
1-10
Использование JMS
Выгоды при использовании JMS:
 Стандартный, независимый от
вендора API
 Приложения использующие JMS
API более переносимы от одного
вендора к другому
 Асинхронные сообщения
1-11
JMS приложения
 Системы которые обрабатывают
маршрутизацию и доставку
сообщений называют JMS Provider
 Приложения использующие JMS
называют JMS Client
 JMS Application это бизнес система
обычно состоящая из множества
JMS Clients и одного JMS Provider
1-12
JMS клиенты
 Клиент который посылает
сообщения называется поставщик
(producer)
 Клиент который получает
сообщения называется
потребитель (consumer)
 Клиент может быть и
потребителем и поставщиком
одновременно
1-13
Destination
Destination это место в JMS сервере где
сообщение ждет пока оно не будет
обработано
1-14
JMS Messaging Domains
JMS определяет две модели доставки:
 Point-to-Point
 Publish/Subscribe
1-15
Терминология
Термины зависят от модели доставки:
1-16
Point-to-Point
Модель доставки сообщений PTP:
 Может быть много отправителей
(senders) и много получателей
(receivers)
 Сообщение получает только один
получатель
 Возможна как асинхронная так и
синхронная отправка сообщений
см. далее
1-17
Point-to-Point
Модель доставки сообщений PTP:
1-18
Publish/Subscribe
Модель доставки сообщений Pub/Sub:
 Позволяет издателям (publishers)
не зависеть от подписчиков
(subscribers), уменьшая связность в
приложении
 Сообщение доставляется всем
подписчикам
 Возможна долговременная
(durable) подписка
см. далее
1-19
Publish/Subscribe
Модель доставки сообщений Pub/Sub:
1-20
Обмен сообщениями в JMS
1-21
Долговременные подписчики
 Регистрируются у JMS Provider`а
 Получают сообщения, которые
были доставлены пока они были
неактивны
 JMS Provider отвечает за
сохранение сообщений для таких
подписчиков
1-22
Выводы
В этой секции мы обсудили:
 Модель доставки сообщений Pointto-Point
 Модель доставки сообщений
Publish/Subscribe
 Долговременных подписчиков
1-23
Рассматриваемые темы
 Понятие обмена сообщениями
 Обзор Java Message Service
 Написание простых JMS клиентов
 Написание простого JMS Producer
 Написание простого JMS Consumer
 Message-Driven Beans
1-24
Создание JMS Producer
Шаги для отправки сообщения
см. далее
1-25
Создание JMS Producer
Шаги для отправки сообщения
1-26
Шаг 1. Поиск ConnectionFactory
Connection Factory:
 Легковесный объект хранящийся в
JNDI
 Используется для создания новых
соединений
 Один из двух типов:
 javax.jms.QueueConnectionFactory
 javax.jms.TopicConnectionFactory
1-27
Шаг 2. Создание Connection
Connection:
 Используется для взаимодействия
с JMS сервером
 Используется для создания сессий
 Один из двух типов:
 javax.jms.QueueConnection
 javax.jms.TopicConnection
1-28
Шаг 3. Создание Session
Session:
 Используется для создания
senders, receivers и messages
 Используется для демаркации
транзакций
 Один из двух типов:
 javax.jms.QueueSession
 javax.jms.TopicSession
1-29
Шаг 4. Поиск Destination
Destination:
 Легковесный объект хранящийся в
JNDI
 Идентифицирует цель (target)
сообщения
 Один из двух типов:
 javax.jms.Queue
 javax.jms.Topic
1-30
Шаг 5. Отправка сообщения
Message Producer:
 Позволяет отправлять сообщение в
destination
 Позволяет определить параметры
доставки
 Один из двух типов:
 javax.jms.QueueSender
 javax.jms.TopicPublisher
1-31
Пример JMS Producer
Context ctx = new InitialContext();
/* Шаг 1. Поиск ConnectionFactory */
QueueConnectionFactory qfactory = (QueueConnectionFactory)
ctx.lookup("queueConnectionFactoryJndiName");
/* Шаг 2. Создание Connection */
QueueConnection qcon = qfactory.createQueueConnection();
/* Шаг 3. Создание Session, не транзакционной */
QueueSession qsession = qcon.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
JMSProducer.java
см. далее
1-32
Пример JMS Producer
/* Шаг 4. Поиск Destination */
Queue queue = (Queue) ctx.lookup("queueJndiName");
/* Шаг 5. Создание Sender и отправка сообщения */
QueueSender qsender = qsession.createSender(queue);
as
TextMessage msg = qsession.createTextMessage();
qcon.start();
msg.setText("Hello JMS world");
qsender.send(msg);
JMSProducer.java
1-33
Модели оповещения
Задается в не транзакционных сессиях:
 Session.AUTO_ACKNOWLEDGE
 Session.CLIENT_ACKNOWLEDGE
 Session.DUPS_OK_ACKNOWLEDGE
1-34
Сообщения в JMS
Класс реализующий javax.jms.Message:
 TextMessage
 MapMessage
 ObjectMessage
 StreamMessage
 BytesMessage
 Можно реализовать свой тип
сообщения
1-35
Создание JMS Consumer
Шаги для получения сообщения
 Чтобы получить сообщение из
destination, Шаги 1-4 совпадают с
приведенными ранее.
 Затем для получения сообщения
используйте:
 QueueBrowser
 QueueReceiver
 TopicSubscriber
1-36
Пример JMS Consumer
// Начальный поиск в JNDI
…
// Создание потребителя сообщений
QueueReceiver qreceiver =
qsession.createReceiver(queue);
qcon.start();
TextMessage message = (TextMessage)
qreceiver.receive();
System.out.println("Message is: " + message.getText());
JMSReceiver.java
1-37
Выводы
В этой секции мы обсудили:
 Создание простого JMS Producer
 Создание простого JMS Consumer
1-38
Рассматриваемые темы
 Понятие обмена сообщениями
 Обзор Java Message Service
 Написание простых JMS клиентов
 Message-Driven Beans
 Архитектура Message-Driven Beans
 Написание JMS MDBs
1-39
Message-Driven Beans
 MDBs это EJB которые потребляют
(consume) сообщения
 Не видны клиенту, не имеют
бизнес интерфейса, клиенты не
получают от них исключений
 Выполняются как stateless сервисы
 Контролируются контейнером
 Сами могут посылать сообщения
1-40
JMS Message-Driven Beans
 Реализуют интерфейс
javax.jms.MessageListener
 Потребляют (consume) сообщения
из очередей (queue) или тем
(topic)
1-41
MDBs как потребители сообщений
1-42
MDB жизнненый цикл
1-43
MessageListenter
Интерфейс javax.jms.MessageListener
package javax.jms;
public interface MessageListener {
void onMessage(javax.jms.Message message);
}
MessageListener.java
1-44
Разработка JMS MDBs
Класс Message-Driven Bean:
 Помечен аннотацией
javax.ejb.MessageDriven, либо
описание содержится в
дескрипторе развертывания
 Содержит конструктор без
параметров (явно или неявно)
см. далее
1-45
Разработка JMS MDBs
Класс Message-Driven Bean:
 Реализует интерфейс слушателя
(для JMS javax.jms.MessageListener)
 Опционально реализует методы
обратного вызова для событий
жизненного цикла @PostConstruct
и/или @PreDestroy
1-46
Аннотация MessageDriven
@Target(TYPE) @Retention(RUNTIME)
public @interface MessageDriven {
java.lang.String name() default "";
java.lang.Class messageListenerInterface() default java.lang.Object.class;
javax.ejb.ActivationConfigProperty[] activationConfig() default {};
java.lang.String mappedName() default "";
java.lang.String description() default "";
}
MessageDriven.java
@Target({}) @Retention(RUNTIME)
public @interface ActivationConfigProperty {
java.lang.String propertyName();
java.lang.String propertyValue();
}
ActivationConfigProperty.java
1-47
Пример @MessageDriven
@MessageDriven(
mappedName = "com.acme.Queue",
name = "WatchProcessMDB",
activationConfig = {
@ActivationConfigProperty(
propertyName = “destinationType",
propertyValue = "javax.jms.Queue")
}
)
public class WatchProcessMDB implements MessageListener {
public void onMessage(Message message) {
// обработать сообщение
}
}
WatchProcessMDB.java
1-48
MessageDrivenContext
// можно инжектить ссылку на MessageDrivenContext, также как для session beans
@Resource MessageDrivenContext mdbContext;
public interface EJBContext {
java.security.Principal getCallerPrincipal();
boolean isCallerInRole(java.lang.String s);
UserTransaction getUserTransaction() throws IllegalStateException;
void setRollbackOnly() throws java.lang.IllegalStateException;
boolean getRollbackOnly() throws java.lang.IllegalStateException;
javax.ejb.TimerService getTimerService() throws java.lang.IllegalStateException;
}
java.lang.Object lookup(java.lang.String s);
…
/* не добавляет ни одного нового метода */
public interface MessageDrivenContext extends EJBContext {}
1-49
Транзакции и MDBs
 Метод onMessage поддерживает
 Container-managed transactions (CMT)
 Bean-managed transactions (BMT)
 Клиентская демаркация транзакций в JMS не
поддерживается
1-50
Модель подтверждения
 Контейнер автоматически отсылает
подтверждение JMS серверу
 Для CMT когда происходит commit
транзакции
 Для BMT чтобы определить модель
подтверждения используется параметр
acknowledgeMode
1-51
Модель подтверждения
Определение Acknowledge Mode:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(
propertyName = "acknowledgeMode",
propertyValue = “Dups-ok-acknowledge"),
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
}
)
1-52
Селектор сообщений
Определение Message Selector:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(
propertyName = "messageSelector",
propertyValue = "JMSPriority >= 6"),
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue")
}
)
1-53
Долговременный подписчик
Определение Durable Subscription:
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(
propertyName = “subscriptionDurability",
propertyValue = “Durable"),
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Topic")
}
)
1-54
Пример MDB
Класс реализации:
@MessageDriven
public class MDBSimple implements MessageListener {
public void onMessage(Message msg) {
if (msg instanceof TextMessage) {
TextMessage t = (TextMessage) msg;
try {
System.out.println("Consumed message: " + t.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
см. далее
MDBSimple.java
1-55
Пример MDB
Дескриптор развертывания:
<ejb-jar …>
<enterprise-beans>
<message-driven>
<ejb-name>MDBSimple</ejb-name>
<ejb-class>com.acme.MDBSimple</ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
<transaction-type>Container</transaction-type>
<message-destination-type>javax.jms.Topic</message-destination-type>
<activation-config>
<activation-config-property>
<activation-config-property-name>destinationType</activation-config-property-name>
<activation-config-property-value>javax.jms.Topic</activation-config-property-value>
</activation-config-property>
</activation-config>
</message-driven>
</enterprise-beans>
</ejb-jar>
ejb-jar.xml
1-56
Выводы
В этой секции мы обсудили:
 Архитектуру MDBs
 Создание JMS MDBs
1-57
Практика
Упражнение
Асинхронная обработка сообщений
с помощью MDB
1-58
Выводы
В этом модуле мы обсудили:
 Обработку сообщений
 Java Message Service
 Message-Driven Beans
1-59