Spring Remoting — Spring + RMI

    Spring Remoting

    Spring framework предоставляет обширные возможности по созданию распределенных приложений. Он не только помогает создавать удаленные службы, но и упрощает доступ к ним. На данный момент в с помощью фреймворка можно организовывать удаленный доступ с помощью большого количества технологий — Caucho’s Hessian и Burlap, собственная реализация удаленного доступа через HTTP, RMI и т.д. Под катом краткий обзор возможностей фреймворка Spring для создания распределенных приложений с помощью RMI.



    Spring Remoting



    Вернемся к примеру, начатому в прошлой статье.

    Был рассмотрен интерфейс Action, представляющий математическую операцию и две его реализации ActionAdd и ActionMultiply:

    public interface Action {
        long performAction(long op1, long op2);
        String getName();
    }
    
    public class ActionAdd implements Action {
        @Override
        public long performAction(long op1, long op2) {
            return op1 + op2;    
        }
    
        @Override
        public String getName() {
            return " + ";
        }
    }
    
    public class ActionMultiply implements Action {
        @Override
        public long performAction(long op1, long op2) {
            return op1 * op2;
        }
    
        @Override
        public String getName() {
            return " * ";
        }
    }
    


    И интерфейс ICalculator с реализацией Calculator:

    public interface ICalculator {
        public void setAction(Action act);
        public String calc(String[] args);
    }
    
    public class Calculator implements ICalculator {
        private Action action;
    
        @Override
        public void setAction(Action action) {
            this.action = action;
        }
    
        @Override
        public String calc(String[] args) {
            long op1 = Long.parseLong(args[0]);
            long op2 = Long.parseLong(args[1]);
            return op1 + action.getName() + op2 + " = " + action.performAction(op1, op2);
        }
    }
    


    Объекты помещались в IoC контейнер spring:

    <beans>
        <bean id="multiply" class="springtest.operations.ActionMultiply" />
        <bean id="add" class="springtest.operations.ActionAdd" />
        
        <bean id="calculator" class="springtest.calculator.Calculator">
            <property name="action" ref="add" />
        </bean>
    </beans>
    


    И из контейнера извлекался уже созданный объект:

    ICalculator calc = (ICalculator) factory.getBean("сalculator");
    System.out.print(calc.calc(new String[] {"30", "60"}));
    


    Распределение.



    Теперь принято решение наше приложение сделать распределенным – один компьютер не справляется с большой вычислительной нагрузкой. Java предоставляет для таких случаев RMI — Remote Method Invocation, программный интерфейс вызова удаленных методов, с помощью которого не так сложно это сделать. Но используя Spring Remoting все получается более чем просто.

    Для создания RMI сервера все, что нам нужно, это объявить в контейнере специальный bean – RMI Service:

    <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName" value="Calculator"/>
        <property name="service" ref="calculator"/>
        <property name="serviceInterface" value="springtest.calculator.ICalculator"/>
        <property name="registryPort" value="1199"/>
    </bean>
    


    Стартуем сервер нашего распределенного приложения:

    public class ActionServer {
        public static void main(String[] args) {
            new ClassPathXmlApplicationContext("xml-beans.xml");
        }
    }
    


    Считывая XML файл, Spring сам сделает все необходимое. Запускаем.

    Mar 24, 2011 5:14:24 PM org.springframework.remoting.rmi.RmiServiceExporter getRegistry
    INFO: Looking for RMI registry at port '1199'
    Mar 24, 2011 5:14:24 PM org.springframework.remoting.rmi.RmiServiceExporter sourcepare
    INFO: Binding service 'Calculator' to RMI registry: RegistryImpl_Stub[UnicastRef [liveRef: 
          [endpoint:[127.0.1.1:1199](remote),objID:[0:0:0, 0]]]]
    


    Сервер готов.

    Теперь нужно сделать клиента. Создадим класс ClientCalculator, представляющий собой обертку для калькулятора:

    public class ClientCalculator {
        private ICalculator calculator;
    
        public void setCalculator(ICalculator calculator) {
            this.calculator = calculator;
        }
    
        public ICalculator getCalculator() {
            return calculator;
        }
    }
    


    Теперь для клиентского приложения создаем свой IoC XML контейнер:

    <beans>
        <bean id="clientCalculator" class="springrmi.client.ClientCalculator">
            <property name="calculator" ref="remoteCalculator"/>
        </bean>
        
        <bean id="remoteCalculator" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
            <property name="serviceUrl" value="rmi://localhost:1199/Calculator"/>
            <property name="serviceInterface" value="springtest.calculator.ICalculator"/>
        </bean>
    </beans>
    


    Для создания и использования удаленных объектов используется RmiProxeFactoryBean, который возвращает необходимый интерфейс. И передает его только что созданной обертке clientCalculator.

    Создаем класс клиента и проверяем:

    public class Client {
        public static void main(String[] args) {
            ApplicationContext factory = new ClassPathXmlApplicationContext("springrmi/client/client-beans.xml");
            ClientCalculator calc = (ClientCalculator) factory.getBean("clientCalculator");
            System.out.print(calc.getCalculator().calc(new String[] {"30", "60"}));
        }
    }
    


    30 + 60 = 90
    


    Все, готово. Мы получили распределенное приложение.

    Исходник:
    http://narod.ru/disk/8319633001/springrmi.tar.gz.html

    Используемые источники:
    http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html

    Кроме RMI, в Spring Remoting так же есть поддержка и других сервисов. Для дальнейшего чтения рекомендую обратиться к указанной выше ссылке.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 5

      0
      Отличная статья! Большое спасибо. Обязательно возьму на вооружение ;-)
        +1
        ICalculator calc = (ICalculator) factory.getBean(«сalculator»);
        System.out.print(calc.getCalculator().calc(new String[] {«30», «60»}));
        Откуда взялся calc.getCalculator(), в интерфейсе такого метода нет.
        0
        Прошу пакет с примера перезалить.
        Закончился срок хранения файла. Файл удален с сервиса.

        Заранее спасибо!
          0
          Увы, файлы потерялись безвозвратно… Но, думаю, технологии за прошедшие 3 года несколько изменились, поэтому вряд ли пример еще актуален.

        Only users with full accounts can post comments. Log in, please.