Главная » Spring » Механизмы RPC, основанные на сообщениях Spring

0

В главе 11 рассказывалось о нескольких механизмах, поддержи- ваемых фреймворком Spring, экспортирования методов компонентов как удаленных служб и вызовов этих служб со стороны клиентов. В этой главе было показано, как реализовать обмен сообщениями между приложениями посредством очередей и тем JMS. Теперь по- пробуем объединить эти две концепции и посмотрим, как реализо- вать вызов удаленных методов, используя JMS в качестве транс- порта.

Фреймворк Spring поддерживает два механизма RPC, основан- ных на сообщениях:

#  сам фреймворк Spring предлагает компонент JmsInvokerService-

Exporter, экспортирующий другие компоненты как службы, ос- нованные на сообщениях, и компонент JmsInvokerProxyFactory- Bean – для клиентов, пользующихся этими службами;

# проект Lingo предлагает аналогичный подход для реализации удаленных взаимодействий на основе сообщений с примене- нием его компонентов JmsServiceExporter и JmsProxyFactoryBean.

Как будет показано ниже, эти два механизма очень похожи друг на друга, но каждый из них имеет свои достоинства и недостатки. Я покажу вам оба подхода, а какой из них лучше подходит для вас, вы решите сами. Начнем с первого механизма реализации JMS- служб, включенного в состав фреймворка Spring.

Механизм RPC, основанный на сообщениях, в фреймворке Spring

Как рассказывалось в главе 11, фреймворк Spring предоставляет несколько способов экспортирования компонентов в виде удален- ных служб. Для экспортирования компонентов в виде RMI-служб мы использовали класс RmiServiceExporter, в виде служб Hessian и Burlap – классы HessianExporter и BurlapExporter, в виде служб HTTP Invoker – класс HttpInvokerServiceExporter. Но в Spring имеется еще один экспортер служб, о котором не рассказывалось в главе 11.

Экспортирование  JMS-службы

Класс JmsInvokerServiceExporter близко напоминает другие классы- экспортеры служб. Обратите внимание на некоторое сходство имен JmsInvokerServiceExporter и HttpInvokerServiceExporter. Если известно, что класс HttpInvokerServiceExporter экспортирует службы, действую- щие по протоколу HTTP, то класс JmsInvokerServiceExporter должен экспортировать службы, действующие по протоколу JMS.

Чтобы показать, как действует класс JmsInvokerServiceExporter, об- ратимся к реализации класса AlertServiceImpl, представленной в лис- тинге 13.6.

Листинг 13.6. AlertServiceImpl – это POJO, обрабатывающий сообщения JMS

package com.habuma.spitter.alerts;

import   org.springframework.mail.SimpleMailMessage; import     org.springframework.mail.javamail.JavaMailSender; import   org.springframework.stereotype.Component;

import   com.habuma.spitter.domain.Spittle;

@Component("alertService")

public  class  AlertServiceImpl  implements  AlertService  { private JavaMailSender mailSender;

private String alertEmailAddress;

public AlertServiceImpl(JavaMailSender mailSender,

String   alertEmailAddress)   { this.mailSender   =   mailSender;      this.alertEmailAddress    =    alertEmailAddress;

}

// Отправляет сообщение

public   void   sendSpittleAlert(final   Spittle   spittle)   { SimpleMailMessage message = new SimpleMailMessage(); String   spitterName   =   spittle.getSpitter().getFullName(); message.setFrom("noreply@spitter.com"); message.setTo(alertEmailAddress);  message.setSubject("New  spittle  from  "  +  spitterName);

message.setText(spitterName + " says: " + spittle.getText()); mailSender.send(message);

}

}

Пока не пытайтесь разобраться во всех тонкостях метода sendSpittleAlert(). Подробнее о том, как отправлять почту с помощью Spring, будет рассказываться ниже, в разделе 15.3. Самое важное, на что следует обратить внимание: AlertServiceImpl – это простой объект POJO и не содержит ничего, что указывало бы на его использование для обработки сообщений JMS. Он реализует простой интерфейс AlertService, представленный ниже:

package   com.habuma.spitter.alerts;   import   com.habuma.spitter.domain.Spittle;

public  interface  AlertService  {

void  sendSpittleAlert(Spittle  spittle);

}

Как видите, AlertServiceImpl отмечен аннотацией @Component, благо- даря которой он обнаруживается и регистрируется как компонент в контексте приложения Spring с идентификатором alertService. Ссылка на этот компонент будет использоваться при настройке компонента JmsInvokerServiceExporter:

<bean  id="alertServiceExporter" class="org.springframework.jms.remoting.JmsInvokerServiceExporter" p:service-ref="alertService" p:serviceInterface="com.habuma.spitter.alerts.AlertService"       />

Свойства этого компонента описывают, как должна выглядеть экспортируемая служба. В свойство service внедряется ссылка на компонент alertService, являющийся реализацией удаленной служ- бы. А в свойстве serviceInterface указывается полное имя класса ин- терфейса, предоставляемого службой.

Свойства экспортера ничего не говорят о том, что служба будет до- ступна по протоколу JMS. Все дело в том, что JmsInvokerServiceExporter определяется как обработчик JMS. То есть его можно объявить внут- ри элемента <jms:listener-container>:

<jms:listener-container   connection-factory="connectionFactory">

<jms:listener     destination="spitter.alert.queue" ref="alertServiceExporter" />

</jms:listener-container>

Контейнеру обработчиков JMS передается ссылка на фабрику соединений, благодаря чему он получает возможность установить соединение с брокером сообщений. А в элементе <jms:listener> ука- зывается имя приемника JMS, куда будут доставляться сообщения.

Доступ к JMS-службе

На данный момент JMS-служба извещений готова к работе и ожи- дает появления RPC-сообщений в очереди с именем spitter.alert. queue. Для доступа к этой службе со стороны клиента будет исполь- зоваться компонент JmsInvokerProxyFactoryBean.

Компонент JmsInvokerProxyFactoryBean очень близко напоминает дру- гие фабричные компоненты, представленные в главе 11, производящие прокси-объекты для доступа к удаленным службам. Он скрывает де- тали взаимодействий с удаленной службой за удобным интерфейсом, посредством которого клиент взаимодействует со службой. Основ- ное отличие заключается в том, что JmsInvokerProxyFactoryBean создает прокси-объекты не для доступа к службам, действующим по прото- колу RMI или HTTP, а для доступа к службам, действующим по про- токолу JMS и экспортируемым компонентом JmsInvokerServiceExporter.

Для доступа к службе извещений компонент JmsInvokerProxyFac- toryBean можно настроить, как показано ниже:

<bean    id="alertService" class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean">

<property name="connectionFactory" ref="connectionFactory" />

<property name="queueName" value="spitter.alert.queue" />

<property name="serviceInterface"

value="com.habuma.spitter.alerts.AlertService" />

</bean>

Свойства connectionFactory и queueName определяют, как должны до- ставляться RPC-сообщения. В данном случае – брокеру сообщений, указанному в настройках фабрики соединений, в очередь с именем spitter.alert.queue. Свойство serviceInterface указывает, что прокси- объект должен действовать через интерфейс AlertService.

Компоненты JmsInvokerServiceExporter и JmsInvokerProxyFactoryBean реализуют в Spring альтернативный способ организации удален- ных взаимодействий по протоколу JMS. Но они – не единственный способ экспортирования и использования служб на основе JMS. И, возможно, они являются даже не самым оптимальным выбором. Познакомимся с особенностями проекта Lingo и посмотрим, что он может предложить сверх того, что предлагает механизм JMS Invoker.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии