2007-03-18

关于远程调用(XFire/HttpInvoker/Hessian etc.)及远程服务管理的一些随想(下)

关键字: Spring xfire webservice soa httpinvoker hessian pool

服务代理生成器( ServiceProxyGenerator )也是一个值得一提的地方,我们先看一下它的接口:

 

  1. /**   
  2.   * 服务代理生成器。   
  3.   *   
  4.   * @author Tony   
  5.   */    
  6. public interface ServiceProxyGenerator {    
  7.   
  8.     /**   
  9.      * 取得服务代理对象。   
  10.      *   
  11.      * @param serviceClass   
  12.      *             服务接口   
  13.      * @param serviceUrl   
  14.      *             服务地址   
  15.      * @param props   
  16.      *             附加属性   
  17.      * @return 代理对象   
  18.      * @throws Exception   
  19.      */    
  20.     Object getService(Class serviceClass, String serviceUrl, Properties props) throws Exception;    
  21. }    
  22.     
  23. /*它只有一个 getService() 方法,那么为什么设计这个接口?在什么地方使用呢?回答这个问题之前先来看看下面这段代码: */  
  24.     public void registService(ServiceModel serviceModel) throws ServiceException {    
  25.         ······    
  26.         String key = serviceModel.getServiceId() + KEY_SPAR    
  27.                      + serviceModel.getServiceClass().getName();    
  28.         if ( serviceNames .contains(key)) {    
  29.             throw new ServiceRegistException( "service is exist!" );    
  30.         }    
  31.         Object proxy = null ;    
  32.         try {    
  33.             ServiceProxyGenerator proxyGenerator = (ServiceProxyGenerator) beanFactory    
  34.                 .getBean(serviceModel.getServiceType() + PROXY_GENERATOR_END );    
  35.             proxy = proxyGenerator.getService(serviceModel.getServiceClass(), serviceModel    
  36.                 .getServiceUrl(), serviceModel.getProps());    
  37.         } catch (Exception e) {    
  38.             throw new ServiceRegistException( "can't regist service !" , e);    
  39.         }    
  40.         if (proxy != null ) {    
  41.             serviceNames .add(key);    
  42.             serviceContainer .put(key, proxy);    
  43.         } else {    
  44.             throw new ServiceRegistException( "fail to regist service !" );    
  45.         }    
  46.     }    

 

 

 上面做特殊标记的代码就是应用服务代理生成器的地方,这里我们用到了 Spring bean 工厂,根据注册服务的类型( xfire,httpinvoker,hessian 等)到 Spring 容器里查找相应的生成器,并生成指定类型的服务。看下面配置的几个服务代理生成器:

xml 代码

 

  1.     
  2.  < bean id = "xfire_generator" class = "com.tonysoft.common.service.repository.generator.XFireServiceProxyGenerator" lazy-init = "true" >    
  3.     < property name = "serviceFactory" >    
  4.         < ref bean = "xfire.serviceFactory" />    
  5.      property >    
  6.   bean >    
  7.   
  8.      
  9.  < bean id = "hessian_generator" class = "com.tonysoft.common.service.repository.generator.HessianServiceProxyGenerator" lazy-init = "true" >    
  10.   bean >    
  11.   
  12.      
  13.  < bean id = "httpinvoker_generator" class = "com.tonysoft.common.service.repository.generator.HttpInvokeServiceProxyGenerator" lazy-init = "true" >    
  14.   bean >    
  15.   
  16.      
  17.  < bean id = "custom_generator" class = "com.tonysoft.common.service.repository.generator.CustomServiceProxyGenerator" lazy-init = "true" >    
  18.   bean >  
  19.   
  20.      
  21.  < bean id = "serviceRepository" class = "com.tonysoft.common.service.repository.DefaultServiceRepository" >    
  22.   bean >    
  23.   
  24.      
  25.  < bean id = "serviceIdProvider" class = "com.tonysoft.common.service.repository.provider.DefaultServiceIdProvider" >    
  26.   bean >    
  27.      
  28.  < bean id = "abstractServiceProxyFactory" class = "com.tonysoft.common.service.repository.ServiceProxyFactory" abstract = "true" >    
  29.   bean >   

 

简单看一下 HttpInvoker 类型服务代理生成器的代码:

java 代码

 

  1. public class HttpInvokeServiceProxyGenerator implements ServiceProxyGenerator {    
  2.   
  3.     /** HttpInvoker 服务代理工厂 */    
  4.     private HttpInvokerProxyFactoryBean httpInvokerFactory = new HttpInvokerProxyFactoryBean();    
  5.     /*   
  6.      * @see com.alipay.xfiredemo.common.ServiceProxyGenerator#getService(java.lang.Class, java.lang.String,   
  7.      *      java.util.Properties)   
  8.      */    
  9.     public Object getService(Class serviceClass, String serviceUrl, Properties props) {    
  10.         // Todo initial httpInvokerFactory with props    
  11.         httpInvokerFactory .setServiceInterface(serviceClass);    
  12.   
  13.         httpInvokerFactory .setServiceUrl(serviceUrl);    
  14.   
  15.         // must invoke this method    
  16.         httpInvokerFactory .afterPropertiesSet();    
  17.   
  18.         return httpInvokerFactory .getObject();    
  19.   
  20.     }    
  21.   
  22. }    

是的,正如你所看到的一样,我们这里把真正生成服务代理的任务交给了 Spring HttpInvokerProxyFactoryBean 来完成。

 

提供在初始化时注册的静态服务功能,配制如下:

  1.   
  2. < bean id = "bootupServiceRegister" class = "com.tonysoft.common.service.repository.register.BootupServiceRegister" lazy-init = "false" >    
  3.        < property name = "services" >    
  4.            < list >    
  5. < bean class = "com.tonysoft.common.service.repository.ServiceModel" >    
  6.                   < property name = "serviceClass" >< value > com.tonysoft.common.service.repository.example.HelloHttpInvoker  value > property >    
  7.                   < property name = "serviceId" >< value > default  value > property >    
  8.                   < property name = "serviceType" >< value > httpinvoker  value > property >    
  9.                   < property name = "serviceUrl" >< value > http://localhost:8080/serviceRepositoryApplication/service/httpInvoker/helloHttpInvoker.service  value > property >    
  10.                   < property name = "props" >    
  11.                      < props > props >    
  12.                    property >    
  13.                bean >    
  14.               < bean class = "com.tonysoft.common.service.repository.ServiceModel" >    
  15.                   < property name = "serviceClass" >< value > com.tonysoft.common.service.repository.example.HelloXFire  value > property >    
  16.                   < property name = "serviceId" >< value > default  value > property >    
  17.                   < property name = "serviceType" >< value > xfire  value > property >    
  18.                   < property name = "serviceUrl" >< value > http://localhost:8080/serviceRepositoryApplication/service/xfire/helloXFire.service?WSDL  value > property >    
  19.                   < property name = "props" >    
  20.                      < props > props >    
  21.                    property >    
  22.                bean >        
  23.             list >    
  24.         property >    
  25.      bean >    

具体内容可以参看附件中的资源:

一、 ServiceRepository 的源代码( Eclipse 工程)

二、 一个示例应用

三、 打包部署的 ANT 脚本

 

把项目导入 Eclipse 中,直接运行 Ant 脚本,在 target 目录下会生成服务中心的 jar 包,同时生成示例应用的 war 包,把 war 包放到任意服务器( Server )上并启动服务器并确保应用正常启动。 运行 ServiceRepositoryTest .java 执行完整的单元测试,观测结果。其他的自己看源码吧。

 

评论
ecsoftcn 2007-03-22   回复
jianfeng008cn 写道
没有Rest的ws吗?


这个自己很容易就可以扩展进来,只需要实现"ServiceProxyGenerator"接口提供获取服务.
jianfeng008cn 2007-03-21   回复
没有Rest的ws吗?
ecsoftcn 2007-03-20   回复
dovecat 写道
恩,确实不错!实际上是服务定位器模式的应用!
ps:我咋没看到附件呢?


附件在第一部分:http://www.javaeye.com/topic/60681
dovecat 2007-03-20   回复
恩,确实不错!实际上是服务定位器模式的应用!
ps:我咋没看到附件呢?
ecsoftcn 2007-03-20   回复
生命火花 写道
为什么要把spring和xfire这样绑在一起!


我习惯于把ws物理独立出来!


不是把XFire和Spring绑在一起,而是通过一个高层的抽象,统一管理各种形式的远程服务。

把ws物理独立出来是什么意思?是专门为ws开一个服务器么?你这里的ws指的是标准的WS,还是指XFire?
生命火花 2007-03-19   回复
为什么要把spring和xfire这样绑在一起!


我习惯于把ws物理独立出来!
XMLDB 2007-03-19   回复
只有代码,随想呢?
shaucle 2007-03-19   回复
用spring 封闭了传统的ws获取方式.使得用起来更方便,也可能更高效.
好文.
发表评论

该博客是同时发布到论坛的,无法评论在论坛已被锁定的帖子

ecsoftcn
搜索本博客
我的相册
88c8175a-c3d2-42a6-bc78-19ab6d7bdcfc-thumb
AromaRI
共 1 张
最近加入圈子
存档
最新评论
评论排行榜