«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();
}
Давайте продолжим объявлять Exporter, который делает сервис доступным для клиентов. В этом случае мы будем использовать 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.
Мы также должны установить имя службы, которое позволяет идентифицировать открытую службу в Реестр РМИ.
С данной конфигурацией клиент сможет связаться с 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.