`
zhaonjtu
  • 浏览: 131124 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Spring的远程服务

阅读更多

  由于项目的关系,接触到spring的远程服务调用,我主要复杂服务端的业务逻辑开发,而且先前的架子已经搭好了,所以先前并未感觉到发布服务的存在,等到想仔细看看远程服务是怎么配置的时候才发现没有看懂,没办法只有看看《Spring in Action》,总算略知一二了。相比起Spring的标准配置而言,项目的配置反而更复杂点,复杂在于那些个有关远程服务的spring bean的配置都是个性化以后的,参数的设置都和标准不同,难怪我看不懂了,不过你如果熟悉原理以后就会发现万变不离其中。 

    为了方便日后复习或者文档的完善的目的,还是现学现卖,看看spring中如何借助自己的组件发布我们的远程服务。

  在Spring中提供了四种类型的远程服务:RMI(老东西),Hessian或BurLap,HTTP invoker,SOAP。如果我们去使用其中的任何一种去发布和调用远程服务,其过程也大致相同。一个一个来吧。以下内容来自对《Spring in Action》的理解。或者可以参考spring 2.0 reference中

写道

http://www.redsaga.com/spring_ref/2.0/html/remoting.html

 

  •    RMI。没有Spring,这个老家伙要用起来还真是麻烦,还要注册,编译什么的。最好的无侵入的框架就是让使用者基本感受不到组件的存在。在服务端,我们就像开发本地的服务一样开发,至于远程的客户端怎么调用我这个服务那就交给Spring做吧,就像一个代理一样。现实中的中介就是这么个作用,在spring中叫做代理。
  • Hessian或Burlap,这两个东东本质上是一样的,只不过前者是二进制流的方式传输,后者是xml消息的方式传输。另外一点就是他们都是基于http的,所以在服务器端就多了一步要配置相关的servelet,dispatcher,controller。
  • Http invoker当然是基于http 的了,所以大致上的配置和Hessian(或Burlap)相同。不同的是是这个是Spring小组自己开发的一直远程服务模型。Spring HTTP调用器使用标准Java序列化机制来通过HTTP暴露业务。如果你的参数或返回值是复杂类型,并且不能通过Hessian和Burlap的序列化机制进行序列化,HTTP调用器就很有优势。
  • soap 暂时不说。如果是客户端调用soap,用spring配置客户端即可,客户端才不去管服务器端是不是用java写的程序。这点与上述三种不一样。  

如果你曾经使用过HTTP invoker来发布过你的服务的话,那么以下的几个类你应该很熟悉了,HttpInvokerProxyFactoryBean,HttpInvokerServiceExporter,DispatcherServlet,BeanNameUrlHandleMapping.

尤其是后面两个。以下是我的对一个远程服务请求过来的在代码层次spring都在干些什么。

场景如下:

   客户端的配置如下:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="accountService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> <property name="serviceUrl"> <value> http://127.0.0.1:8080/TestService-server/remoting.service</value> </property> <property name="serviceInterface"> <value>test.AccountService </value> </property> </bean> </beans>

 

  服务器端:

  web.xml部分内容

 

<servlet> <servlet-name>remoting</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>remoting</servlet-name> <url-pattern>*.service</url-pattern> </servlet-mapping>

 

  remoting-servelet.xml

 

<beans> <bean id="accountService" class="test.AccountServiceImpl"> <!-- any additional properties, maybe a DAO? --> </bean> <bean name="/remoting.service" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> <property name="service" ref="accountService" /> <property name="serviceInterface" value="test.AccountService" /> </bean> </beans>

 

好了:现在服务器开始启动了。我们只关心我们感兴趣的地方,先睹为快吧,看看那只tomcat的log

2008-11-21 17:23:57,906 DEBUG [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping] - Looking for URL mappings in application context: org.springframework.web.context.support.XmlWebApplicationContext: display name [WebApplicationContext for namespace 'remoting-servlet']; startup date [Fri Nov 21 17:23:57 CST 2008]; root of context hierarchy; config locations [/WEB-INF/remoting-servlet.xml]
2008-11-21 17:23:57,906 DEBUG [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping] - Rejected bean name 'accountService'
2008-11-21 17:23:57,906 DEBUG [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping] - Found URL mapping [/remoting.service]
2008-11-21 17:23:57,906 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Returning cached instance of singleton bean '/remoting.service'
2008-11-21 17:23:57,906 DEBUG [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping] - Mapped URL path [/remoting.service] onto handler [org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter@11f139b]
2008-11-21 17:23:57,906 INFO [org.springframework.web.servlet.DispatcherServlet] - No HandlerMappings found in servlet 'remoting': using default
2008-11-21 17:23:57,906 DEBUG [org.springframework.core.CollectionFactory] - Creating [java.util.LinkedHashMap]
2008-11-21 17:23:57,921 INFO [org.springframework.web.servlet.DispatcherServlet] - No HandlerAdapters found in servlet 'remoting': using default
2008-11-21 17:23:57,921 DEBUG [org.springframework.core.CollectionFactory] - Creating [java.util.LinkedHashMap]
2008-11-21 17:23:57,921 DEBUG [org.springframework.core.CollectionFactory] - Creating [java.util.LinkedHashMap]
2008-11-21 17:23:57,937 INFO [org.springframework.web.servlet.DispatcherServlet] - No ViewResolvers found in servlet 'remoting': using default
2008-11-21 17:23:57,937 INFO [org.springframework.web.servlet.DispatcherServlet] - FrameworkServlet 'remoting': initialization completed in 484 ms
2008-11-21 17:23:57,937 INFO [org.springframework.web.servlet.DispatcherServlet] - Servlet 'remoting' configured successfully

大部分是关于 DispatcherServlet的log。下面看看服务端的两个比较重要的类:

 

 httpInvokeServiceExporter和SimpleUrlHandleMaping,有的时候可以只用前者就可以,这个时候默认使用

BeanNameUrlHandleMapping。后者负责请求url和bean的映射,前者复杂将指定的bean导出成http invoke service。
原文如下:Web controller that exports the specified service bean as HTTP invoker service endpoint,

accessible via an HTTP invoker proxy.
实现SimpleUrlHandleMaping的实例在初始化的时候会调用initApplicationContext()方法,这个方法是其父类

ApplicationObjectSupport的方法,通过重写initApplicationContext()
我们可以实现自己的url Mapping逻辑,事实上继承自AbstractUrlHandlerMapping的两个子类SimpleUrlHandleMaping,

BeanNameUrlHandleMapping也是这么干的。

在自定义的initApplicationContext()方法中一般会实现自定义的解析url的逻辑,然后根据url和handle的关系作为键值

对保存在AbstractUrlHandlerMapping.handlerMap
中去,这样每当以后有远程service请求过来的时候我们就调用getHandlerInternal(HttpServletRequest request)去到

handleMap中去找对应的handle。
那handle是个什么东东呢,handle一般是实现httpInvokeServiceExporter的一个实例,而且设置了service,

serviceInterface等属性,可以通过httpInvokerProxy访问。。

好,到这里一些大概可以想像的东西可以想到了,客户端提交了一个请求比如:http://127.0.0.1:8080/TestService-

server/remoting.service,当这个请求
到达服务器端的时候,负责处理这些个url的servelet正等着呢,很容易理解这个请求被抛给了remoting这个

DispatcherServelet。
<servlet>
 <servlet-name>remoting</servlet-name>
 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
 <servlet-name>remoting</servlet-name>
 <url-pattern>*.service</url-pattern>
</servlet-mapping>
在没有弄清楚具体的实现逻辑之前,我们仍然可以想象一下大致的过程。DispatcherServelet会找到对应的控制器也就是

BeanNameUrlHandleMapping,然后调用
getHandlerInternal(HttpServletRequest request)方法得到一个handle。

DispatcherServelet本身也是一个HttpServlet在初始化的时候会调用inti,在初始化的过程中会调用

initHandlerMappings(),这个方法
将实现HandlerMapping接口的全部保存在handlerMappings中,比如BeanNameUrlHandleMapping
。等到DispatcherServelet需要处理processRequest时,dispatcher会调用getHandler去调用BeanNameUrlHandleMapping

的getHandle
返回包装过Handle的HandlerExecutionChain,如return new HandlerExecutionChain(handler,

this.adaptedInterceptors);
随后dispatcher会在doDispatch()中做处理,代码如下:
// Actually invoke the handler.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

其实到这里服务端的工作差不多了。

分享到:
评论

相关推荐

    spring远程调用简单实例

    首先,我们要明确Spring远程调用(Remoting)的基本概念。远程调用是指应用程序的不同组件或服务之间,通过网络进行通信的一种方式。Spring支持多种远程调用协议,如RMI(Remote Method Invocation)、Hessian、 ...

    Spring远程调用使用http方式

    首先,我们需要理解什么是Spring远程调用。Spring Remote提供了一种机制,使得应用程序能够跨越网络边界调用其他服务的方法,仿佛它们是在同一进程中执行一样。HTTP远程调用是Spring Remote的一种实现方式,通过HTTP...

    Spring攻略PDF版

    因为上传大小的限制,分为两部分上传,这是第二部分,... 第16章 Spring远程服务和Web服务   第17章 Spring对EJB和JMS的支持   第18章 Spring对JMX、电子邮件和调度的支持   第19章 Spring中的脚本编程 

    spring远程调用

    5. **客户端调用**:最后,客户端可以像调用本地对象一样调用远程服务。我们只需要获取HttpInvokerProxyFactoryBean创建的代理对象,然后直接调用接口方法即可。 ```java @Autowired private UserService ...

    使用spring远程调用服务端接口实现WebService功能

    在Java EE平台上,Spring框架提供了一种强大的方式来实现远程服务调用,特别是通过其HttpInvokerServiceExporter组件来实现基于HTTP的WebService功能。这个技术允许客户端和服务端通过HTTP协议进行通信,实现远程...

    Spring攻略中文版PDF

    因为上传大小的限制,分为两部分上传,这是第一部分,... 第16章 Spring远程服务和Web服务   第17章 Spring对EJB和JMS的支持   第18章 Spring对JMX、电子邮件和调度的支持   第19章 Spring中的脚本编程 

    Spring in Action 2nd Edition

    - **Spring远程服务**:Spring框架支持多种远程服务调用机制,如RMI、HTTP invoker等,简化了远程服务的开发和部署。 5. **Web层支持** - **Spring MVC**:Spring框架提供了一种模型-视图-控制器(Model-View-...

    Spring攻略英文版(附带源码)

    Spring专家力作 理论与实践完美结合 问题描述→解决方案... 第16章 Spring远程服务和Web服务   第17章 Spring对EJB和JMS的支持   第18章 Spring对JMX、电子邮件和调度的支持   第19章 Spring中的脚本编程 

    Spring 远程调用 -- C# 访问java WEB 服务

    标题中的"Spring 远程调用"指的是Spring的远程服务访问(Remote Service Access,RSA)。RSA允许服务提供者创建远程服务,而服务消费者可以跨网络调用这些服务。在Web服务上下文中,Spring提供了WebServiceTemplate...

    spring cloud feign实现远程调用服务传输文件的方法

    Spring Cloud Feign 是一个基于 Java 的声明式 RESTful 客户端,提供了一种简单、可靠的方式来调用远程服务。在本文中,我们将介绍如何使用 Spring Cloud Feign 实现远程调用服务传输文件的方法。 Feign 介绍 ...

    Spring 实现远程访问详解——rmi

    Spring远程访问通过使用普通POJOs,能更容易的开发远程访问服务。目前,Spring远程访问的主要技术如下: 1. 远程调用RMI(Remote Method Invocation): 通过使用 RmiProxyFactoryBean 和 RmiServiceExporter,并且,...

    Spring整合Hessian访问远程服务

    本篇文章将深入探讨如何将Spring与Hessian整合,以便在分布式系统中轻松实现远程服务调用。 首先,让我们理解Spring整合Hessian的基本原理。Spring通过其强大的IoC(Inversion of Control)容器管理服务和客户端,...

    Spring 实现远程访问详解——httpinvoker

    上文我们利用Spring rmi实现了Spring的远程访问(Spring 实现远程访问详解——rmi),本文主要讲解利用HttpInvoke实现远程访问。 Spring httpInvoker使用标准java序列化机制,通过Http暴露业务服务。如果你的参数和...

    spring RMI 远程接口调用

    在Spring中,RMI的实现被集成到IoC(Inversion of Control)容器中,这样可以方便地管理和配置远程服务。 服务端的实现通常包括以下步骤: 1. **定义远程接口**:这是服务端提供给客户端调用的接口,需要使用`@...

    springboot以FTP方式上传文件到远程服务器

    "Spring Boot 使用 FTP 方式上传文件到远程服务器" 在本文中,我们将详细介绍如何使用 Spring Boot 框架来实现 FTP 方式上传文件到远程服务器。FTP(File Transfer Protocol)是一种常用的文件传输协议,广泛应用于...

    Spring配置hessian远程服务

    使用eclipse maven工程搭建hessian远程服务demo 分服务端的整合和客户端 建议阅读相关博客http://blog.csdn.net/heisemuyangquan/article/details/79460528

    spring远程调用和xfire aegis 源代码上传

    标题 "spring远程调用和xfire aegis 源代码上传" 涉及到的是在Java开发中使用Spring框架进行远程过程调用(RPC)以及整合XFire和Aegis库来实现服务间的通信。这一主题是分布式系统设计中的一个重要组成部分,特别是...

    spring-boot+webSocket实现向日葵远程控制

    本项目为spring-boot+webSocket实现的向日葵远程控制项目 向日葵是一款很好用的远程操作软件。 一直很好奇这种软件的基本原理是如何的? 今天带大家通过一个简单的项目来探究一下,并实现一个简单的远程操控软件 ...

    spring-remote-service-example:一个示例项目,用于展示如何使用 JSON 反序列化通过 HTTP 在隔离的 Spring 容器之间进行(远程)服务调用

    首先,理解Spring远程服务调用的核心概念。Spring Remoting是Spring框架的一部分,它提供了一种透明的方式来调用远程服务,仿佛它们是本地对象一样。这包括了RMI、Hessian、 Burlap以及HTTP-based协议如Web Services...

Global site tag (gtag.js) - Google Analytics