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