1. Обзор
Вызов удаленного метода
Java позволяет вызывать объект, находящийся в другой виртуальной машине Java
. Это хорошо зарекомендовавшая себя технология, но несколько громоздкая в использовании, как мы можем видеть в официальном следе Oracle, посвященном этой теме.
В этой быстрой статье мы рассмотрим, как Spring Remoting
позволяет использовать RMI
более простым и понятным способом.
Эта статья также завершает обзор Spring Remoting
. Вы можете найти информацию о других поддерживаемых технологиях в предыдущих выпусках: HTTP Invokers , JMS , AMQP , Hessian и Burlap .
2. Зависимости Maven
Как и в наших предыдущих статьях, мы собираемся настроить пару приложений Spring Boot
: сервер, который предоставляет удаленный вызываемый объект, и клиент, который вызывает открытую службу.
Все, что нам нужно, находится в банке spring-context
, поэтому мы можем использовать любой помощник Spring Boot
, который мы предпочитаем, потому что наша главная цель — просто иметь доступ к основным библиотекам.
Теперь давайте перейдем к обычному spring-boot-starter-web
, не забывая удалить зависимость Tomcat
, чтобы исключить встроенный веб-сервис:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
3. Серверное приложение
Мы начнем объявлять интерфейс, определяющий сервис для заказа поездки на такси, который в конечном итоге будет доступен клиентам:
public interface CabBookingService {
Booking bookRide(String pickUpLocation) throws BookingException;
}
Затем мы определим bean-компонент, реализующий интерфейс. Это bean-компонент, который фактически будет выполнять бизнес-логику на сервере:
@Bean
CabBookingService bookingService() {
return new CabBookingServiceImpl();
}
Продолжим объявлять экспортер
, который делает сервис доступным для клиентов. В этом случае мы будем использовать RmiServiceExporter
:
@Bean
RmiServiceExporter exporter(CabBookingService implementation) {
Class<CabBookingService> serviceInterface = CabBookingService.class;
RmiServiceExporter exporter = new RmiServiceExporter();
exporter.setServiceInterface(serviceInterface);
exporter.setService(implementation);
exporter.setServiceName(serviceInterface.getSimpleName());
exporter.setRegistryPort(1099);
return exporter;
}
Через setServiceInterface()
мы предоставляем ссылку на интерфейс, который будет доступен удаленно.
Мы также должны предоставить ссылку на объект, фактически выполняющий метод с помощью setService()
. Затем мы могли бы указать порт реестра RMI,
доступный на машине, на которой работает сервер, если мы не хотим использовать порт по умолчанию 1099.
Мы также должны установить имя службы, которое позволяет идентифицировать выставленную службу в реестре RMI .
С данной конфигурацией клиент сможет связаться с CabBookingService
по следующему URL-адресу: rmi://HOST:1199/CabBookingService
.
Давайте, наконец, запустим сервер. Нам даже не нужно запускать реестр RMI самостоятельно, потому что Spring
сделает это автоматически за нас, если такой реестр недоступен.
4. Клиентское приложение
Давайте теперь напишем клиентское приложение.
Мы начинаем объявлять RmiProxyFactoryBean
, который создаст bean-компонент с тем же интерфейсом, который предоставляет служба, работающая на стороне сервера, и который будет прозрачно направлять вызовы, которые он получит, на сервер:
@Bean
RmiProxyFactoryBean service() {
RmiProxyFactoryBean rmiProxyFactory = new RmiProxyFactoryBean();
rmiProxyFactory.setServiceUrl("rmi://localhost:1099/CabBookingService");
rmiProxyFactory.setServiceInterface(CabBookingService.class);
return rmiProxyFactory;
}
Давайте затем напишем простой код, который запускает клиентское приложение и использует прокси-сервер, определенный на предыдущем шаге:
public static void main(String[] args) throws BookingException {
CabBookingService service = SpringApplication
.run(RmiClient.class, args).getBean(CabBookingService.class);
Booking bookingOutcome = service
.bookRide("13 Seagate Blvd, Key Largo, FL 33037");
System.out.println(bookingOutcome);
}
Теперь достаточно запустить клиент, чтобы убедиться, что он вызывает службу, предоставленную сервером.
5. Вывод
В этом руководстве мы увидели, как мы можем использовать Spring Remoting
, чтобы упростить использование RMI
, которое в противном случае потребует ряда утомительных задач, таких как, среди прочего, запуск реестра и определение служб с использованием интерфейсов, которые интенсивно используют проверенные исключения.
Как обычно, вы найдете исходники на GitHub.