Удаленный вызов метода (RMI) : Spring поддерживает RMI через RmiProxyFactoryBean и RmiServiceExporter. RmiServiceExporter экспортирует любой управляемый Spring компонент в качестве службы RMI и регистрирует. RmiProxyFactoryBean — это фабричный компонент, создающий прокси для службы RMI. Этот прокси-объект взаимодействует с удаленными службами RMI от имени клиента.
HTTP-инициатор Spring : Spring-HTTP-инициаторы используют стандартный механизм сериализации Java для предоставления сервисов через HTTP. Spring поддерживает инфраструктуру HTTP invoker через HttpInvokerProxyFactoryBean и HttpInvokerServiceExporter. HttpInvokerServiceExporter, который экспортирует указанный компонент службы в качестве конечной точки службы HTTP invoker, доступный через прокси HTTP invoker. HttpInvokerProxyFactoryBean — это фабричный компонент для прокси-серверов HTTP invoker.
Hessian: Hessian предлагает двоичный протокол удаленного взаимодействия на основе HTTP. Spring поддерживает Hessian через HessianProxyFactoryBean и HessianServiceExporter.
Мешковина: Мешковина — основанная на XML альтернатива Коши Гессиану. Spring предоставляет классы поддержки, такие как BurlapProxyFactoryBean и BurlapServiceExporter.
JAX-RPC: Spring обеспечивает поддержку удаленного взаимодействия для веб-служб через JAX-RPC (API веб-службы J2EE 1.4).
JAX-WS: Spring обеспечивает поддержку удаленного взаимодействия для веб-служб через JAX-WS (преемник JAX-RPC, представленный в Java EE 5 и Java 6).
JMS: поддержка удаленного взаимодействия JMS в Spring предоставляется классами JmsInvokerServiceExporter и JmsInvokerProxyFactoryBean.
Давайте посмотрим на поддержку Spring RMI для разработки Spring RMI Service & Client.
Используемые технологии:
  JDK 1.6.0_31 
  Весна 3.1.1 
  Maven 3.0.2 
ШАГ 1: СОЗДАТЬ MAVEN ПРОЕКТ
Maven проект создается как показано ниже. (Его можно создать с помощью Maven или IDE Plug-in).
ШАГ 2: БИБЛИОТЕКИ
Spring-зависимости добавляются в pom.xml Maven.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | <!-- Spring 3.1.x dependencies --><properties>    <spring.version>3.1.1.RELEASE</spring.version></properties> <dependencies>            <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-core</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context</artifactId>        <version>${spring.version}</version>    </dependency><dependencies> | 
ШАГ 3: СОЗДАЙТЕ ПОЛЬЗОВАТЕЛЬСКИЙ КЛАСС
Новый класс пользователя создан.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | packagecom.otv.user; importjava.io.Serializable; /** * User Bean * * @author  onlinetechvision.com * @since   24 Feb 2012 * @version 1.0.0 * */publicclassUser implementsSerializable {     privatelongid;    privateString name;    privateString surname;     /**     * Get User Id     *     * @return long id     */    publiclonggetId() {        returnid;    }     /**     * Set User Id     *     * @param long id     */    publicvoidsetId(longid) {        this.id = id;    }     /**     * Get User Name     *     * @return long id     */    publicString getName() {        returnname;    }     /**     * Set User Name     *     * @param String name     */    publicvoidsetName(String name) {        this.name = name;    }     /**     * Get User Surname     *     * @return long id     */    publicString getSurname() {        returnsurname;    }     /**     * Set User Surname     *     * @param String surname     */    publicvoidsetSurname(String surname) {        this.surname = surname;    }     @Override    publicString toString() {        StringBuilder strBuilder = newStringBuilder();        strBuilder.append("Id : ").append(getId());        strBuilder.append(", Name : ").append(getName());        strBuilder.append(", Surname : ").append(getSurname());        returnstrBuilder.toString();    }} | 
ШАГ 4: СОЗДАЙТЕ ИНТЕРФЕЙС ICacheService
Интерфейс ICacheService, представляющий интерфейс службы удаленного кэша, создан.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | packagecom.otv.cache.service; importjava.util.concurrent.ConcurrentHashMap; importcom.otv.user.User; /** * Cache Service Interface * * @author  onlinetechvision.com * @since   27 Feb 2012 * @version 1.0.0 * */publicinterfaceICacheService {     /**     * Get User Map     *     * @return ConcurrentHashMap User Map     */    publicConcurrentHashMap<long, user> getUserMap(); } | 
ШАГ 5: СОЗДАЙТЕ CacheService CLASS
Класс CacheService создается путем реализации интерфейса ISchedulerService. Предоставляет доступ к удаленному кешу…
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | packagecom.otv.cache.service; importjava.util.concurrent.ConcurrentHashMap; importcom.otv.user.User; /** * Cache Service Implementation * * @author  onlinetechvision.com * @since   6:04:49 PM * @version 1.0.0 * */publicclassCacheService implementsICacheService {     //User Map is injected...    ConcurrentHashMap<long, user> userMap;     /**     * Get User Map     *     * @return ConcurrentHashMap User Map     */    publicConcurrentHashMap<long, user> getUserMap() {        returnuserMap;    }     /**     * Set User Map     *     * @param ConcurrentHashMap User Map     */    publicvoidsetUserMap(ConcurrentHashMap<long, user> userMap) {        this.userMap = userMap;    } } | 
ШАГ 6: СОЗДАЙТЕ ИНТЕРФЕЙС IRMIUserService
IRMIUserService Интерфейс, представляющий интерфейс службы RMI, создан. Кроме того, он предоставляет удаленные методы для клиентов RMI …
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | packagecom.otv.rmi.server; importjava.util.List; importcom.otv.user.User; /** * RMI User Service Interface * * @author  onlinetechvision.com * @since   24 Feb 2012 * @version 1.0.0 * */publicinterfaceIRMIUserService {     /**     * Add User     *     * @param  User user     * @return boolean response of the method     */    publicbooleanaddUser(User user);     /**     * Delete User     *     * @param  User user     * @return boolean response of the method     */    publicbooleandeleteUser(User user);     /**     * Get User List     *     * @return List user list     */    publicList<User> getUserList(); } | 
ШАГ 7: СОЗДАЙТЕ RMIUserService CLASS
Класс RMIUserService (он же объект RMI) создается путем реализации интерфейса IRMIUserService.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | packagecom.otv.rmi.server; importjava.util.ArrayList;importjava.util.List;importorg.apache.log4j.Logger; importcom.otv.cache.service.ICacheService;importcom.otv.user.User; /** * RMI User Service Implementation * * @author  onlinetechvision.com * @since   24 Feb 2012 * @version 1.0.0 * */publicclassRMIUserService implementsIRMIUserService {     privatestaticLogger logger = Logger.getLogger(RMIUserService.class);     //Remote Cache Service is injected...    ICacheService cacheService;     /**     * Add User     *     * @param  User user     * @return boolean response of the method     */    publicbooleanaddUser(User user) {        getCacheService().getUserMap().put(user.getId(), user);        logger.debug("User has been added to cache. User : "+getCacheService().getUserMap().get(user.getId()));        returntrue;    }     /**     * Delete User     *     * @param  User user     * @return boolean response of the method     */    publicbooleandeleteUser(User user) {        getCacheService().getUserMap().put(user.getId(), user);        logger.debug("User has been deleted from cache. User : "+user);        returntrue;    }     /**     * Get User List     *     * @return List user list     */    publicList<User> getUserList() {        List<User> list = newArrayList<User>();        list.addAll(getCacheService().getUserMap().values());        logger.debug("User List : "+list);        returnlist;    }     /**     * Get RMI User Service     *     * @return IRMIUserService RMI User Service     */    publicICacheService getCacheService() {        returncacheService;    }     /**     * Set RMI User Service     *     * @param IRMIUserService RMI User Service     */    publicvoidsetCacheService(ICacheService cacheService) {        this.cacheService = cacheService;    }} | 
ШАГ 8: СОЗДАТЬ RMIServerStarter CLASS
RMI Server Starter Class создан. Запускает сервер RMI.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | packagecom.otv.rmi.server.starter; importorg.springframework.context.support.ClassPathXmlApplicationContext; /** * RMI Server Starter * * @author  onlinetechvision.com * @since   27 Feb 2012 * @version 1.0.0 * */publicclassRMIServerStarter {     publicstaticvoidmain(String[] args) {         //RMI Server Application Context is started...        newClassPathXmlApplicationContext("rmiServerAppContext.xml");    }} | 
ШАГ 9: СОЗДАТЬ rmiServerAppContext.xml
Содержимое контекста приложения сервера RMI показано ниже.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |     xsi:schemaLocation="http://www.springframework.org/schema/beans      <!-- Beans Declaration -->    <beanid="UserMap"class="java.util.concurrent.ConcurrentHashMap"/>     <beanid="CacheService"class="com.otv.cache.service.CacheService">        <propertyname="userMap"ref="UserMap"/>    </bean>        <beanid="RMIUserService"class="com.otv.rmi.server.RMIUserService">        <propertyname="cacheService"ref="CacheService"/>    </bean>     <!-- RMI Server Declaration -->    <beanclass="org.springframework.remoting.rmi.RmiServiceExporter">         <!-- serviceName represents RMI Service Name -->        <propertyname="serviceName"value="RMIUserService"/>         <!-- service represents RMI Object(RMI Service Impl) -->        <propertyname="service"ref="RMIUserService"/>         <!-- serviceInterface represents RMI Service Interface exposed -->        <propertyname="serviceInterface"value="com.otv.rmi.server.IRMIUserService"/>         <!-- defaults to 1099 -->        <propertyname="registryPort"value="1099"/>    </bean> </beans> | 
ШАГ 10: СОЗДАТЬ RMIServiceClient CLASS
Класс RMIServiceClient создан. Он вызывает службу пользователя RMI и выполняет пользовательские операции.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | packagecom.otv.rmi.client; importorg.apache.log4j.Logger;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext; importcom.otv.rmi.server.IRMIUserService;importcom.otv.rmi.server.RMIUserService;importcom.otv.user.User; /** * RMI Service Client * * @author  onlinetechvision.com * @since   24 Feb 2012 * @version 1.0.0 * */publicclassRMIServiceClient {     privatestaticLogger logger = Logger.getLogger(RMIUserService.class);     /**     * Main method of the RMI Service Client     *     */    publicstaticvoidmain(String[] args) {         logger.debug("RMI Service Client is starting...");         //RMI Client Application Context is started...        ApplicationContext context = newClassPathXmlApplicationContext("rmiClientAppContext.xml");         //Remote User Service is called via RMI Client Application Context...        IRMIUserService rmiClient = (IRMIUserService) context.getBean("RMIUserService");         //New User is created...        User user = newUser();        user.setId(1);        user.setName("Bruce");        user.setSurname("Willis");         //The user is added to the remote cache...        rmiClient.addUser(user);         //The users are gotten via remote cache...        rmiClient.getUserList();         //The user is deleted from remote cache...        rmiClient.deleteUser(user);         logger.debug("RMI Service Client is stopped...");    }} | 
ШАГ 11: СОЗДАТЬ rmiClientAppContext.xml
Содержимое контекста клиентского приложения RMI показано ниже.
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 |     xsi:schemaLocation="http://www.springframework.org/schema/beans      <!-- RMI Client Declaration -->    <beanid="RMIUserService"class="org.springframework.remoting.rmi.RmiProxyFactoryBean">         <!-- serviceUrl represents RMI Service Url called-->        <propertyname="serviceUrl"value="rmi://x.x.x.x:1099/RMIUserService"/>         <!-- serviceInterface represents RMI Service Interface called -->        <propertyname="serviceInterface"value="com.otv.rmi.server.IRMIUserService"/>         <!-- refreshStubOnConnectFailure enforces automatic re-lookup of the stub if a                            call fails with a connect exception -->        <propertyname="refreshStubOnConnectFailure"value="true"/>     </bean> </beans> | 
ШАГ 12: ЗАПУСК ПРОЕКТА
Если RMI Service Client запускается при запуске RMI Server, ниже будут показаны журналы вывода RMI Server. Кроме того, RMI-сервер и клиент можно запустить, открыв две отдельные консоли через вашу IDE. :
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ....04.03.2012 14:23:15 DEBUG (RmiBasedExporter.java:59) - RMI service [com.otv.rmi.server.RMIUserService@16dadf9] is an RMI invoker04.03.2012 14:23:15 DEBUG (JdkDynamicAopProxy.java:113) - Creating JDK dynamic proxy: target sourceis SingletonTargetSource fortarget object [com.otv.rmi.server.RMIUserService@16dadf9]04.03.2012 14:23:15  INFO (RmiServiceExporter.java:276) - Binding service 'RMIUserService'to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[192.168.1.7:1099](local),objID:[0:0:0, 0]]]]04.03.2012 14:23:15 DEBUG (AbstractAutowireCapableBeanFactory.java:458) - Finished creating instance of bean 'org.springframework.remoting.rmi.RmiServiceExporter#0'04.03.2012 14:23:15 DEBUG (AbstractApplicationContext.java:845) - Unable to locateLifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@3c0007]04.03.2012 14:23:15 DEBUG (AbstractBeanFactory.java:245) - Returning cached instance of singleton bean 'lifecycleProcessor' 04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.addUser04.03.2012 14:25:43 DEBUG (RMIUserService.java:33) - User has been added to cache. User : Id : 1, Name : Bruce, Surname : Willis04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.addUser 04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.getUserList04.03.2012 14:25:43 DEBUG (RMIUserService.java:57) - User List : [Id : 1, Name : Bruce, Surname : Willis]04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.getUserList 04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.deleteUser04.03.2012 14:25:43 DEBUG (RMIUserService.java:45) - User has been deleted from cache. User : Id : 1, Name : Bruce, Surname : Willis04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.deleteUser 04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:73) - Incoming RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.getUserList04.03.2012 14:25:43 DEBUG (RMIUserService.java:57) - User List : []04.03.2012 14:25:43 DEBUG (RemoteInvocationTraceInterceptor.java:79) - Finished processing of RmiServiceExporter remote call: com.otv.rmi.server.IRMIUserService.getUserList | 
ШАГ 13: СКАЧАТЬ
Справка: поддержка Spring Remoting и разработка службы RMI от нашего партнера JCG Эрен Авсарогуллари в блоге Online Technology Vision .
