Spring HttpInvoker的封装


Spring HttpInvoker的简单封装,优点如下:

1、客户端无xml配置
2、客户端基于接口调用,无需知道接口的服务名。
(大众型使用方式:接口可以打成jar分发到服务端和客户端程序使用。我是使用maven构建项目,所以建立了一个service-code项目供serviceProject和clientProject引用)
3、服务端只需配置简单的2步骤,后面介绍。

封装文件一共7个类,先分别说下客户端和服务端的使用配置,再解释原理:

SpringMVCApplicationContextUtil.java

SpringRemoteServiceContext.java

RemoteServiceDescService.java

DefaultRemoteServiceDescServiceImpl.java

HttpInvokerRemoteServiceDescContainer.java

HttpInvokerClientServiceFactory.java

RemoteConnectFailureExceptionExt.java

客户端调用服务的示例代码如下:

HttpInvokerClientServiceFactory.init();//只需初始化一次
String serverURL = "http://localhost:8080/liangfa-analysis";//服务地址
//获得远程服务TestService,就像是调用本地服务那样(自行捕获通信异常)
TestService testService = HttpInvokerClientServiceFactory.getService(serverURL, TestService.class);
//调用服务
testService.sayHello();
//客户端api是不是很简单?? 只需要一个HttpInvokerClientServiceFactory就搞定了 : )

服务端的2处配置:

1、配置远程服务文件remoting-servlet.xml,除了配置业务有关的服务(如TestService),需要加入RemoteServiceDescService,服务名约定为“/remote/remoteServiceDesc”

(HttpInvokerRemoteServiceDescContainer中有常量配置)

<!--暴漏远程服务:服务列表描述 required-->
    <bean name="RemoteServiceDescService" class="com.ksource.liangfa.ws.core.util.remote.DefaultRemoteServiceDescServiceImpl">
    </bean>
    <bean name="/remote/remoteServiceDesc" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="RemoteServiceDescService"></property>
        <property name="serviceInterface" value="com.ksource.liangfa.ws.core.util.remote.RemoteServiceDescService"/>
    </bean>

    <!--测试服务-->
    <bean name="/remote/TestService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="RemoteTestService"></property>
        <property name="serviceInterface" value="com.ksource.liangfa.ws.core.service.datacenter.TestService"/>
    </bean>
......其他服务.......

 
2、初始化服务描述的上下文(remoting-servlet.xml)

SpringRemoteServiceContext.initContext(SpringMVCApplicationContextUtil.getWebApplicationContext(config.getServletContext(), "springServletName"));

我的做法是在项目的初始化servlet(SystemInit.init)里调用,如下:
配置web.xm,在项目启动servlet里

<servlet>
        <servlet-name>SystemInit</servlet-name>
        <servlet-class>com.ksource.syscontext.SystemInit</servlet-class>
        <load-on-startup>3</load-on-startup>
  </servlet>

  

 public class SystemInit extends HttpServlet {
  
      @Override
      public void init(ServletConfig config) throws ServletException {
		SpringRemoteServiceContext.initContext(SpringMVCApplicationContextUtil.getWebApplicationContext(config.getServletContext(), "springServlet"));
	.......
	.......
	}
  }

  

   
实现思路:

SpringMVCApplicationContextUtil用于获取spring mvc的bean容器,这个容器包含了spring mvc配置文件里配置的bean(同样包含remoting-servlet.xml)

DefaultRemoteServiceDescServiceImpl本身也是暴漏的服务,但他的作用主要是用于描述服务端暴漏的服务,有点类WSDL的意味。

SpringRemoteServiceContext通过bean容器找出暴漏的服务,保存到map中

public class SpringRemoteServiceContext {
 private static Map<String, HttpInvokerServiceExporter> servicesMap;
 public static void initContext(
   ApplicationContext applicationContext) {
  servicesMap = applicationContext.getBeansOfType(HttpInvokerServiceExporter.class);
 }
 public static Map<String, HttpInvokerServiceExporter> getServicesMap(){
  return servicesMap;
 }
}

 
HttpInvokerRemoteServiceDescContainer用于保存一个服务端的全部接口的服务地址。

HttpInvokerClientServiceFactory用于根据接口名称,来获取远程服务对象。
HttpInvokerClientServiceFactory.getService(String serverUrl, Class<T> clazz)方法,会根据
serverUrl来获取HttpInvokerRemoteServiceDescContainer对象,然后通过服务描述来创建HttpInvokerProxyFactoryBean对象,然后HttpInvokerProxyFactoryBean.getObject()来得到远程服务。

大致思路如上,整理的比较乱,可参见源码,包名可自行修改后使用。

猜你喜欢

转载自tou3921.iteye.com/blog/1729111