技术开发 频道

SCA服务框架扩展实践

【IT168 技术文档】

    业务组要求ASF提供多种方式的远程服务访问,兼顾性能和跨平台的不同需求,因此在原有的Web Service的SCA发布及绑定的功能外,集成了Hessian,用以发布和访问内部服务(安全性和跨平台要求不高,性能要求较高的服务)。在文中将要讲的就是如何将一个外部的开源项目集成到基于SCA规范实现的服务框架中。
    注:ASF(Application Service Framework)是基于Tuscany作为解析内核,再次封装和扩展的符合SCA规范的服务框架,SCA基本元数据解析依赖于Tuscany内核部分,组件解析组装以及扩展根据SCA规范实现。

设计与实现

    根据需求并且结合SCA的extend规范,只需要采用binding extension的方式,提供实现:

  1. 在ASF框架中将业务发布成Hessian服务可被ASF内部服务组装调用。
  2. 在ASF框架中将业务发布成Hessian服务可被外部调用。
  3. ASF框架中的服务能够绑定外部发布的Hessian服务。

    扩展插件实现步骤:

    1. SCA配置的解析。(采用实现StAXArtifactProcessor接口)


图1

    Read是读入配置文件时应该如何解析标签中的内容,write是动态将运行期内容写入到配置文件中(一般应该很少用)。getArtifactType是返回所要解析的具体内容,也就是后面要提到的Model。Resolve是根据SCA配置文件解析的结果和通过已经解析的一些资源作再次的逻辑组装,应该算是业务逻辑的解析处理。

    2. 创建Hessian服务的发布提供实现以及调用绑定提供实现。(此处的切入点是实现BindingProviderFactory)


图2

    提供了创建服务绑定提供的接口实现和服务调用绑定的接口实现。

    3. 将扩展插件接入到ASF框架中(采用实现ModuleActivator接口)


图3

    只有开始和结束模块插件的两个方法,这儿就是将上面两部分需要注册的内容注册到服务框架中,服务框架根据需要解析的Model来做处理。这里和上面都提到了Model,同时也可以看到上面两个接口都是采用泛型的设计,其实所有的处理都是围绕着Model来做的,后面会有全局的类图,就一目了然了。

    Hessian绑定插件全类图(分成三块作为图形展示):


图4

    这部分类图中的四个类相对来说比较独立,其中HessianBindingProviderFactory和HessianBindingActivator已经解释过了,前者的作用在于产生Hessian Binding的服务提供者实现和引用者实现,后者是作为注册到服务框架中去的接入点。ASFHessianServlet在第一次开发过程中是没有实现的,直接采用HessianServlet去处理远端Hessian请求,但是在后续的测试过程中发现了问题,就扩展了HessianServlet,后面会提到此问题。ASFHessianConfigurator是对Hessian服务提供者提供一些必要的配置信息。


图5

    这个类图囊括了Hessian服务提供者和调用者的实现以及与Hessian Model之间的关系。可以看到服务的提供者和调用者都是围绕着HessianServiceBinding来定义操作。HessianServiceBinding是扩展了Binding和Extensible的一个接口,由于在前面已经提到,当前所要做的扩展只是Component中的Binding,因此继承了Binding接口,同时作为良好的可扩展性,继承了Extensible接口,允许继续被扩展。HessianServiceBindingImpl是Binding扩展的具体实现,内部包含了在扩展标签中所包含的属性,用来提供给Binding服务提供者和Binding服务引用者使用。在服务的真正提供者和调用者的实现外部多做了一层封装,用来提供例如回调和异步服务处理的机制。


图6

    上图中几个类主要负责SCA标签解析实现,通过工厂类动态组装解析实现,然后将工厂类注册到ASF解析扩展库中,在解析到对应的Qname的时候调用工厂类来生成解析器去解析配置信息。

    Hessian绑定插件流程图:


图7

    上图描述的是基本的几个流程:插件的解析与注册, Hessian服务的发布与绑定, Hessian服务调用和处理。

    问题:

    1. 插件载入先后的问题。
    Hessian需要内嵌Web Container支持,当前ASF框架中内嵌了两个Web Container:Tomcat和Jetty,自己倾向于使用Jetty作为轻量级的内置Web Container。但是在插件载入初始化的过程中有依赖于Jetty插件,但Jetty插件还没有被启动,导致了Hessian插件无法启动。解决方法就是在Hessian插件激活的配置文件中,将Jetty也一起启动(支持一个文件配置多个插件),然后Jetty放置在Hessian前面。这个解决了启动的问题,但是可能导致重复启动多个相同的插件,以后需要考虑根据插件启动的情况来判断是否已经启动插件,只需要使用现有已启动的插件,防止重复启动,浪费资源。

    2. 需要注入服务的服务作为Hessian发布的问题。

    问题描述:
    将某个接口实现发布成为Hessian服务,如果此服务定义需要注入其他ASF中的服务,注入失效。
    问题定位:
    开始设计服务端提供服务的时候,只是简单的将所需要发布的服务接口和实现传递给HessianServlet,然后让HessianServlet自己创建逻辑实现来处理,但是这样每次都是简单的通过实例化来构造业务处理对象,根本没有去读取配置文件来注入ASF的服务。
    问题解决:
    重载HessianServlet,通过服务发布提供者构造时传递给HessianServlet所需要使用的ASF内部组件,在Servlet的service方法中用组件创建业务Proxy,然后调用具体的方法并返回结果,这里的Proxy已经将需要注入的服务注入到了业务逻辑实现中。

0
相关文章