Главная » Spring » Использование RMI Spring

0

Имеющие достаточно продолжительный опыт разработки прило- жений на языке Java наверняка слышали (и, возможно, использова- ли) механизм вызова удаленных методов (Remote Method Invocation, RMI). Поддержка RMI, впервые появившаяся в JDK 1.1, обеспе- чивает широкие возможности удаленных взаимодействий между программами на языке Java. До появления поддержки RMI Java- программистам был доступен единственный механизм удаленных взаимодействий – CORBA (требовавший приобретения стороннего брокера объектных запросов (Object Request Broker, ORB)), иначе приходилось опускаться на низкий уровень и заниматься програм- мированием сокетов.

Однако и с применением механизма RMI реализация доступа к удаленным службам весьма утомительна и требует вручную писать немалый объем кода. Фреймворк Spring упрощает модель RMI, предо- ставляя фабричный компонент, создающий прокси-объекты, который позволяет внедрять службы RMI в приложения на основе Spring, как если бы они были локальными компонентами JavaBeans. Spring также предоставляет объект-экспортер, упрощающий преобразование ком- понентов, управляемых фреймворком Spring, в службы RMI.

На примере приложения Spitter я покажу, как внедрить службу RMI в контекст клиентского приложения на основе Spring. Но снача- ла посмотрим, как можно использовать объект-экспортер для экспор- тирования реализации компонента SpitterService в виде службы RMI.

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

Если прежде вам приходилось создавать службы RMI, вы уже знаете, что этот процесс состоит из нескольких этапов:

1.   Написать класс, реализующий службу, с методами, возбуждаю- щими исключение java.rmi.RemoteException.

2.   Создать интерфейс службы, расширяющий java.rmi.Remote.

3.   Запустить RMI-компилятор (rmic), чтобы создать классы-за- готовки для реализации клиента и сервера.

4.   Запустить RMI-реестр, где будет выполняться служба.

5.   Зарегистрировать службу в RMI-реестре.

М-да! Слишком много, чтобы организовать работу простенькой службы RMI. Но хуже всего, что тут и там могут возбуждаться ис- ключения RemoteExceptions и MalformedURLExceptions. Обычно эти ис- ключения свидетельствуют о фатальных ошибках, обработка кото-

рых не имеет большого смысла, но вы вынуждены будете писать массу шаблонного кода, перехватывающего и обрабатывающего их даже при том, что это практически бессмысленно.

Очевидно, что организация службы RMI связана с большим объ- емом ручной работы. А может фреймворк Spring как-то исправить эту ситуацию?

Настройка службы RMI в Spring

К счастью, фреймворк Spring предоставляет простой способ пуб- ликации служб RMI. Вместо того чтобы писать классы, учитываю- щие особенности RMI, с методами, возбуждающими исключение RemoteException, достаточно написать POJO, реализующий функцио- нальность службы, а все остальное Spring возьмет на себя.

Служба RMI, которая будет создана далее, экспортирует методы интерфейса SpitterService. В качестве напоминания в листинге 11.1 приводится объявление этого интерфейса.

Листинг 11.1. Интерфейс SpitterService определяет службу для приложения Spitter

package  com.habuma.spitter.service; import    java.util.List;

import  com.habuma.spitter.domain.Spitter; import   com.habuma.spitter.domain.Spittle;

public interface SpitterService {

List<Spittle> getRecentSpittles(int count); void  saveSpittle(Spittle  spittle);

void saveSpitter(Spitter spitter); Spitter getSpitter(long id);

void  startFollowing(Spitter  follower,  Spitter  followee);

List<Spittle> getSpittlesForSpitter(Spitter spitter); List<Spittle> getSpittlesForSpitter(String username); Spitter getSpitter(String username);

Spittle getSpittleById(long id); void deleteSpittle(long id);

List<Spitter> getAllSpitters();

При традиционном подходе к реализации службы RMI все эти методы в SpitterService и в SpitterServiceImpl должны были бы быть объявлены как возбуждающие исключение java.rmi.RemoteException. Но в данном случае предполагается, что подобный интерфейс и его реализация будут превращены в службу RMI с использованием компонента RmiServiceExporter, входящего в состав Spring, поэтому существующей реализации вполне достаточно.

Компонент RmiServiceExporter способен экспортировать любые компоненты Spring как службы RMI. Как отмечено на рис. 11.4, компонент RmiServiceExporter обертывает требуемый компонент клас- сом адаптера. Затем класс-адаптер заносится в реестр RMI и вы- полняет передачу запросов классу службы, в данном случае классу SpitterServiceImpl.

Рис. 11.4. Компонент RmiServiceExporter превращает POJO в службу RMI, обертывая его адаптером службы

и регистрируя адаптер в реестре RMI

Самый простой способ задействовать RmiServiceExporter для экс- портирования SpitterServiceImpl в виде службы RMI состоит в том, чтобы выполнить соответствующие настройки в конфигурационном XML-файле Spring, как показано ниже:

<bean    class="org.springframework.remoting.rmi.RmiServiceExporter" p:service-ref="spitterService" p:serviceName="SpitterService"

p:serviceInterface="com.habuma.spitter.service.SpitterService" />

Здесь компонент spitterService внедряется в свойство service, что- бы сообщить компоненту RmiServiceExporter, что он должен экспор- тировать данный компонент как службу RMI. Свойство serviceName определяет имя службы RMI. А свойство serviceInterface – интер- фейс, который реализует служба.

По умолчанию компонент RmiServiceExporter попытается соеди- ниться с реестром RMI, действующим на локальном компьютере и принимающим запросы на порту с номером 1099. Если на этом порту реестр RMI не будет обнаружен, RmiServiceExporter попытается запустить его. Если необходимо установить связь с реестром RMI на другом порту и/или на другом компьютере, параметры соедине- ния можно настроить с помощью свойств registryPort и registryHost. Например, при следующих настройках компонент RmiServiceExporter попытается установить соединение с реестром RMI, действующим на компьютере rmi.spitter.com и порту с номером 1199:

<bean    class="org.springframework.remoting.rmi.RmiServiceExporter" p:service-ref="spitterService" p:serviceName="SpitterService"

p:serviceInterface="com.habuma.spitter.service.SpitterService" p:registryHost="rmi.spitter.com"

p:registryPort="1199"/>

Это все настройки, необходимые Spring, чтобы превратить ком- понент в службу RMI. Теперь, когда экспортирование службы вы- полнено, можно приступать к созданию альтернативного пользова- тельского интерфейса или предложить сторонним разработчикам создать новые клиентские приложения для Spitter, использующие службу RMI. Разработчики этих клиентских приложений легко смогут реализовать соединение со RMI-службой Spitter, если они также используют фреймворк Spring. А теперь повернемся в дру- гую сторону и посмотрим, как реализовать клиента, пользующегося RMI-службой Spitter.

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

По теме:

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