`
zhaonjtu
  • 浏览: 129753 次
  • 性别: 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远程调用使用http方式

    Spring远程调用使用http方式,将server和client直接部署后,进入http://localhost/HttpClientSpringRMIClient/即可

    Spring攻略PDF版

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

    spring远程调用简单实例

    spirng远程调用可运行简单实例。包含所需所有jar spring-*-3.*.RELEASE.jar aopalliance.jar等。

    Spring攻略中文版PDF

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

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

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

    spring远程调用

    使用 spring 的 httpinvoker 进行远程调用

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

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

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

    适合有spring框架的javaEE平台,出自spring的HttpInvokerServiceExporter导出器,依赖Spring.jar

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

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

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

    Spring 远程调用 -- C# 访问java WEB 服务,之前写的Demo,希望对大家有所帮帮助!

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

    主要介绍了spring cloud feign实现远程调用服务传输文件的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Spring 实现远程访问详解——jms和activemq

    前几章我们分别利用spring rmi、httpinvoker、httpclient、webservice技术实现不同服务器间的远程访问。本章我将通过spring jms和activemq实现单Web项目服务器间异步访问和多Web项目服务器间异步访问。 一. 简介 1. ...

    Spring配置hessian远程服务

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

    java 实现上传文件到远程服务器

    java实现上传文件到远程服务器(spring mvc)

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

    说得简单就是直接通过spring requestmapping即请求映射url访问远程服务。 1. 远程访问流程 1) 服务器在控制器定义远程访问请求映射路径 2) 客户端通过apache httpclient的 httppost方式访问远程服务 2. Httpclient...

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

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

    struts2.3.4+spring3.2.0+hibernate4+hibernate_generic_dao 全注释+远程调用

    struts2.3.4+spring3.2.0+hibernate4+hibernate_generic_dao struts hibernate spring最大化使用注释 基于spring的远程调用

    spring RMI 远程接口调用

    spring RMI 远程接口调用 包含服务端客户端程序,可完整运行

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

    Spring Web Services 是基于 Spring 框架的 Web 服务框架,主要侧重于基于文档驱动的Web服务,提供 SOAP 服务开发,允许通过多种方式创建 Web 服务。本章利用Apache CXF构建和开发webservice. 1. webservice远程...

    基于Spring的远程访问与Web Service

    基于Spring的远程访问与Web Service

Global site tag (gtag.js) - Google Analytics