Удаленный вызов метода (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
|
package com.otv.user; import java.io.Serializable; /** * User Bean * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */public class User implements Serializable { private long id; private String name; private String surname; /** * Get User Id * * @return long id */ public long getId() { return id; } /** * Set User Id * * @param long id */ public void setId(long id) { this.id = id; } /** * Get User Name * * @return long id */ public String getName() { return name; } /** * Set User Name * * @param String name */ public void setName(String name) { this.name = name; } /** * Get User Surname * * @return long id */ public String getSurname() { return surname; } /** * Set User Surname * * @param String surname */ public void setSurname(String surname) { this.surname = surname; } @Override public String toString() { StringBuilder strBuilder = new StringBuilder(); strBuilder.append("Id : ").append(getId()); strBuilder.append(", Name : ").append(getName()); strBuilder.append(", Surname : ").append(getSurname()); return strBuilder.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
|
package com.otv.cache.service; import java.util.concurrent.ConcurrentHashMap; import com.otv.user.User; /** * Cache Service Interface * * @author onlinetechvision.com * @since 27 Feb 2012 * @version 1.0.0 * */public interface ICacheService { /** * Get User Map * * @return ConcurrentHashMap User Map */ public ConcurrentHashMap<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
|
package com.otv.cache.service; import java.util.concurrent.ConcurrentHashMap; import com.otv.user.User; /** * Cache Service Implementation * * @author onlinetechvision.com * @since 6:04:49 PM * @version 1.0.0 * */public class CacheService implements ICacheService { //User Map is injected... ConcurrentHashMap<long, user> userMap; /** * Get User Map * * @return ConcurrentHashMap User Map */ public ConcurrentHashMap<long, user> getUserMap() { return userMap; } /** * Set User Map * * @param ConcurrentHashMap User Map */ public void setUserMap(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
|
package com.otv.rmi.server; import java.util.List; import com.otv.user.User; /** * RMI User Service Interface * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */public interface IRMIUserService { /** * Add User * * @param User user * @return boolean response of the method */ public boolean addUser(User user); /** * Delete User * * @param User user * @return boolean response of the method */ public boolean deleteUser(User user); /** * Get User List * * @return List user list */ public List<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
|
package com.otv.rmi.server; import java.util.ArrayList;import java.util.List;import org.apache.log4j.Logger; import com.otv.cache.service.ICacheService;import com.otv.user.User; /** * RMI User Service Implementation * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */public class RMIUserService implements IRMIUserService { private static Logger logger = Logger.getLogger(RMIUserService.class); //Remote Cache Service is injected... ICacheService cacheService; /** * Add User * * @param User user * @return boolean response of the method */ public boolean addUser(User user) { getCacheService().getUserMap().put(user.getId(), user); logger.debug("User has been added to cache. User : "+getCacheService().getUserMap().get(user.getId())); return true; } /** * Delete User * * @param User user * @return boolean response of the method */ public boolean deleteUser(User user) { getCacheService().getUserMap().put(user.getId(), user); logger.debug("User has been deleted from cache. User : "+user); return true; } /** * Get User List * * @return List user list */ public List<User> getUserList() { List<User> list = new ArrayList<User>(); list.addAll(getCacheService().getUserMap().values()); logger.debug("User List : "+list); return list; } /** * Get RMI User Service * * @return IRMIUserService RMI User Service */ public ICacheService getCacheService() { return cacheService; } /** * Set RMI User Service * * @param IRMIUserService RMI User Service */ public void setCacheService(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
|
package com.otv.rmi.server.starter; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * RMI Server Starter * * @author onlinetechvision.com * @since 27 Feb 2012 * @version 1.0.0 * */public class RMIServerStarter { public static void main(String[] args) { //RMI Server Application Context is started... new ClassPathXmlApplicationContext("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 --> <bean id="UserMap" class="java.util.concurrent.ConcurrentHashMap" /> <bean id="CacheService" class="com.otv.cache.service.CacheService"> <property name="userMap" ref="UserMap"/> </bean> <bean id="RMIUserService" class="com.otv.rmi.server.RMIUserService" > <property name="cacheService" ref="CacheService"/> </bean> <!-- RMI Server Declaration --> <bean class="org.springframework.remoting.rmi.RmiServiceExporter"> <!-- serviceName represents RMI Service Name --> <property name="serviceName" value="RMIUserService"/> <!-- service represents RMI Object(RMI Service Impl) --> <property name="service" ref="RMIUserService"/> <!-- serviceInterface represents RMI Service Interface exposed --> <property name="serviceInterface" value="com.otv.rmi.server.IRMIUserService"/> <!-- defaults to 1099 --> <property name="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
|
package com.otv.rmi.client; import org.apache.log4j.Logger;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext; import com.otv.rmi.server.IRMIUserService;import com.otv.rmi.server.RMIUserService;import com.otv.user.User; /** * RMI Service Client * * @author onlinetechvision.com * @since 24 Feb 2012 * @version 1.0.0 * */public class RMIServiceClient { private static Logger logger = Logger.getLogger(RMIUserService.class); /** * Main method of the RMI Service Client * */ public static void main(String[] args) { logger.debug("RMI Service Client is starting..."); //RMI Client Application Context is started... ApplicationContext context = new ClassPathXmlApplicationContext("rmiClientAppContext.xml"); //Remote User Service is called via RMI Client Application Context... IRMIUserService rmiClient = (IRMIUserService) context.getBean("RMIUserService"); //New User is created... User user = new User(); 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 --> <bean id="RMIUserService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> <!-- serviceUrl represents RMI Service Url called--> <property name="serviceUrl" value="rmi://x.x.x.x:1099/RMIUserService"/> <!-- serviceInterface represents RMI Service Interface called --> <property name="serviceInterface" value="com.otv.rmi.server.IRMIUserService"/> <!-- refreshStubOnConnectFailure enforces automatic re-lookup of the stub if a call fails with a connect exception --> <property name="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 source is SingletonTargetSource for target 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 locate LifecycleProcessor 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 .
