背后的想法HTTPInvokerServiceExporter
是提供一个端点来接收删除方法调用。
在服务器端,很容易配置 a RemoteExporter
,声明要公开的接口并将其关联到将处理调用的真实 bean。
在客户端上,必须配置RemoteAcessor
基本上需要在服务器端访问的接口。
通过 HTTP 的实现可以使用服务器端的HttpInvokerServiceExporter来完成,如下例所示:
服务接口:
package foo.bar.services;
public interface MyService {
public int sum(int num1, int num2);
}
对于此服务,您将有一个实现(比方说foo.bar.services.DefaultMyService
)。
spring 上下文的说明和配置如下所示:
<bean name="myService" class="foo.bar.DefaultMyService" />
<bean name="/myService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="myService"/>
<property name="serviceInterface" value="foo.bar.MyService"/>
</bean>
使用此配置,我只是打算在最简单的情况下,在由(bean name)映射的 URL 上的接口MyService
下公开我的实现的实例,除了将 URL 映射到具有 URL 值的 bean 之外什么都不做(本例)。foo.bar.MyService
/myService
BeanNameUrlHandlerMapping
/myService
在客户端(消费者),您将配置一个 bean,仅声明您希望远程端公开的接口。对于我们的服务将是这样的:
<bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://foo.bar.org/springSample/myService"/>
<property name="serviceInterface" value="foo.bar.MyService"/>
</bean>
在 spring 在客户端实例化 bean 的那一刻,代理被实例化,然后每个方法调用都将被序列化并通过 HTTP 发送到端点(在这种情况下http://foo.bar.org/springSample/myService
)。在服务器端,这个请求被反序列化和解释,即调用方法暴露的真实服务(在我们的例子中为 DefaultMyService)。该服务将返回一些将被序列化并作为结果给客户端执行的 HTTP 请求的内容。客户端将接收它并反序列化它并将其返回给原始方法调用器.
如您所见(并从 Spring 文档中获得):
服务器端将
反序列化远程调用对象并序列化远程调用结果对象。像 RMI 一样使用 Java 序列化,但提供与 Caucho 基于 HTTP 的 Hessian 和 Burlap 协议相同的易于设置。
客户端将
序列化远程调用对象和反序列化远程调用结果对象。像 RMI 一样使用 Java 序列化,但提供与 Caucho 基于 HTTP 的 Hessian 和 Burlap 协议相同的易于设置。
在这种情况下,与 Spring Remoting 一起使用的序列化是 Java 序列化,这意味着 HTTP 请求包含一个包含序列化对象的实体主体(请记住,在这种情况下,JVM 版本和类版本需要兼容)。
展示是作为一个整体完成的,您无法将它分开URL
,为该接口的每个方法都提供一个。因此,使用 Spring MVC 并创建一个控制器(@Controller
)会更容易为您在接口上将其注释为@RequestMapping
(使用所需 URL)的每个方法实现一个方法,并按如下示例调用服务上的方法:
控制器示例
package foo.bar;
import foo.bar.service.MyService;
@Controller
public class MyService {
@Autowired
private MyService myService;
@RequestMapping("/sum/{num1}/{num2}")
public int sum(@PathVariable("num1") int num1, @PathVariable("num2") int num2) {
return myService.sum(num1, num2);
}
}
使用上下文配置
<context:component-scan base-package="foo.bar"/>
它会自动映射在foo.bar 和包下找到的类,这意味着实现Service
(DefaultMyService
@Service
@Autowired
但这将通过 REST 接口公开您的服务,这意味着它将处理可以由其他消费者(如 PHP 消费者)完成的 HTTP 普通请求(这不能用 Spring Remoting 完成,因为它使用纯 Java 序列化)。
如果您的客户端是 Java,您可以明确地使用 Remoting 并将您的服务作为一个整体公开,如果不是,使用 Spring MVC 的 REST 实现是一个很好的解决方案。
弹簧文档可以在这里找到