CXF:an architectural overview of CXF

本文翻译自http://cxf.apache.org/docs/cxf-architecture.html,cxf架构综述

1、首先来看看

 

 

Bus:

通过BUS对扩展、拦截器、属性等注册。作为CXF的骨架,提供了CXF运行时的共享资源。这些资源包括WSDL、绑定工厂的管理。Bus可以很容易扩展以便包含你自己的资源和服务,或者你可以替换默认的资源(比如http destination factory基于Jetty换为Tomcat)。这种扩展性使依赖注入成为可能,而总线的默认实现正是基于Spring框架,所以各种运行时的组件(包括CXF)得以很方便的使用。
SpringBusFactory将会扫描你应用classpath下META-INF/cxf的所有配置文件,并将其构建于spring的application内,这些文件包括:
META-INF/cxf/cxf.xml (e.g., in cxf-rt-core only)
META-INF/cxf/cxf-extension.xml (e.g. in cxf-rt-bindings-soap)
META-INF/cxf/cxf-property-editors.xml (e.g. in cxf-rt-transports-http)

 


Front-end:
Front-ends提供了一个创建server的编程模型,可以理解为一个门面。提供了JAX-WS, JAX-RS, Simple和Javascript的API用来创建Service,并且各个前端相互独立。通过拦截器来提供功能添加到Services和Endpoints

不推荐使用simple-front-end,除非你的应用无法使用annotation、或者处于使用更小的依赖,否则推荐使用jax-ws作为前端。这里有一个simple-frontend的例子http://cxf.apache.org/docs/simple-frontend.html

 

 

Messaging & Interceptors:
提供了一个低阶的消息和管道,以便在此基础上构建大部分的功能。
CXF是建立在一个通用的消息传递层由消息,拦截器,InterceptorChains组成。拦截器是功能的基本单元。通过分割消息如何处理和发送,这给了CXF非常灵活的架构。它可以在任何时候重新配置,这也使得CXF能够暂停和恢复拦截器链。拦截器有一个方法,handleMessage,可以允许对消息进行操作。这些拦截器可以建立成拦截器链。一些拦截器的例子包括:

  • 解析SOAP的header到DOM元素
  • 拦截器WS-Security对接收的消息进行解密或授权处理
  • 输出的数据绑定将结果序列化

拦截器是单向的,本质上是不知道他们是否正在处理一个请求、响应或错误。 


Phase Interceptors
CXF提供了一个InterceptorChain实现,叫做PhaseInterceptorChain。当拦截器添加到链,他们会按照一定的顺序分配在阶段中,而PhaseInterceptor就是来指定这种顺序的拦截器

举例来说,现在在解析一个SOAP消息,可能涉及两个阶段:
1、dispatch阶段解析SOAP的headers并决定该消息路由到哪个service
2、解码阶段将SOAP的body通过JAXB绑定到对象
在第一个调度阶段我们可以通过两个拦截器来实现:首先一个ReadHeadersInterceptor来解析头,第二个是WS-AddressingInInterceptor来决定调用哪些服务。在第二个解码阶段,我们只用一个JAXBUnmarshallerIntercptor来实现。ReadHeadersInterceptor和AddressingInInterceptor要实现拦截器的阶段,需要在调用getPhase()时返回“dispatch”给PhaseInterceptorChain即可,此外ReadHeadersInterceptor可以在Interceptor.getBefore()方法被调用时返回拦截器AddressingInInterceptor的id来指定想要运行在AddressingInInterceptor之前。之前提到链非常动态和灵活,在上述示例中,我们可以对指定的服务添加拦截器来实现,甚至我们可以暂停链来等等待外部链的完成,就像服务端异步调用一样。

 
Fault Handling
在处理期间的任何一点,一个拦截器都可能抛出错误,或者衍生出错误如SoapFault。这将导致链停止调用和释放,释放的顺序与handleFault在每个拦截器被调用以相反的顺序。InterceptorChains有作为错误的观察者功能,一旦拦截器链被释放,导致错误的原因随着错误拦截器被触发。错误的观察者也可能触发新的链,以便用来调用指定的拦截器来处理错误。

 

Exchanges
除了一个Message的概念,还有一个Exchanges,他持有当前消息exchange的进入、出去和错误的消息的引用。它还拥有exchange的特定属性,而不只是消息。例如Exchange持有当前调用的Service。

 

Reentrant InterceptorChains

PhaseInterceptorChain的一个有趣特性是可重入。这个功能很强大但也有点危险,这个特性只用于CXF在输出一个消息期间。SoapOutInterceptor是最好的例子:

public void handleMessage(Message m) {
  writeSoapEnvelopeStart();
  writeSoapBodyStart();

  // invoke next interceptor, which writes the contents of the SOAP Body
  m.getInterceptorChain().doIntercept(m);
  writeSoapBodyEnd();

  writeSoapEnvelopeEnd();
}

 

 

Service Model:

Services是一个用类WSDL来描述服务的模型。服务模型是CXF内在服务的表述。由两部分组成,第一、用ServiceInfo用来描述WSDL格式的模型包括服务的操作、绑定、端点和模式。第二、有Service本身,包含了ServiceInfo,数据绑定信息、拦截器、服务属性等。

一个服务可以从许多不同来源包括类和WSDL(1.1或2.0)构建。通常前端通过服务工厂来创建这样的服务。工厂组件如ServerFactoryBean和ClientProxyFactoryBean可以用于前端来创建、发布和消费服务。工厂类建立服务模型和配置服务拦截器、数据绑定等更多信息。

服务模型(Service)自己包含ServiceInfo类,下图描述了服务模型子包的API

 

Pluggable Data Bindings: 

Data Bindings

数据绑定实现了XML和JAVA对象之间的映射。数据绑定将数据与XML相互转化,产生的XML schema,并支持wsdl2java生成代码,并不是所有的数据绑定类型都支持这些功能,但一个绑定至少要提供数据转换的功能。从数据绑定架构的细节来看,现在主要支持的绑定包括JAXB 2.x (default), Aegis, Apache XMLBeans, Service Data Objects (SDO) and JiBX

以2.7.0为例JAXB绑定位于cxf-rt-databinding-jaxb-2.7.0.jar

 

Protocol Bindings: 

协议绑定提供了对协议的解释功能。

绑定提供方法来映射传输层顶层实体的格式和协议。一个绑定包含两个主要部分:BindingFactory和Binding。BindingFactory根据服务模型的BindingInfo来创建Binding。绑定包含当前绑定指定的拦截器,还实现了createMessage()方法,后者针对特定的绑定实现消息的创建

CXF当前支持以下四种协议:SOAP1.1、SOAP1.2、REST/HTTP, pure XML和CORBA.

 

The Soap Binding

最典型的绑定是SOAP。它有自己的消息类称为SoapMessage。它增加了能够保持当前消息的SoapVersion和header。

Soap绑定还添加了一种特殊类型的拦截器称为SoapInterceptor,他添加了两个方法:

Set<URI> getRoles();

Set<QName> getUnderstoodHeaders();

这些将告之SOAP拦截器去处理特定的SOAP拦截器的header和roles

 

还有很多拦截器用来处理SOAP消息:

StaxInInterceptor:  对消息中的输入流InputStream创建XMLStreamReader

ReadHeadersInterceptor: 读取SOAP流中的headers放到SoapMessage的Headers

MustUnderstandInterceptor: 负责检查must-understand SOAP头是否全部处理,未处理则抛出错误

SoapOutInterceptor: 负责将返回消息放入输出拦截链中,并启动输出拦截链。

以2.7.0为例,主要位于cxf-rt-bindings-soap-2.7.0.jar

 

Additional Bindings

其他的协议绑定包括REST/HTTP, pure XML, 和CORBA.

 

 

Transports: 

TransportFactory创建目的地(接收)和管道(发送)。CXF为了隐藏绑定和前端层的特定协议,实现了自己的抽象传输层。当前支持的传输协议包括HTTP, HTTPs, HTTP-Jetty, HTTP-OSGI, Servlet, local, JMS, In-VM和许多其他通过camel协议对CXF的支持如SMTP/POP3, TCP and Jabber

 

Conduits

管道是消息输出的基础,管道是由ConduitInitiator创建。发送消息这个动作包括如下的流程:

1、调用conduit.prepare(message): 

这里将开启消息发送,在这点上管道可能已经初始化一个连接,打开了输出流等待指定的消息写入到该输出流中

2、调用conduit.close(message): 

这将关闭或丢弃正在发送中的消息。一个消息的发送者也可以在Conduit注册一个MessageObserver,如果管道是同步的,MessageObserver将会被通知一旦在相应被接收到

 

Destinations

Destinations是接收消息的基础,DestinationFactory创建一个destination

DestinationFactoryManager dfManager = bus.getExtension(DestinationFactoryManager.class);
// Find a DestinationFactory for the SOAP HTTP transport
DestinationFactory df = dfManager.getDestinationFactory("http://schemas.xmlsoap.org/wsdl/soap/http");
// TODO: outline building of EndpointInfo
EndpointInfo endpointInfo = ...;
Destination destination = df.getDestination(endpointInfo);
MessageObservers can then be registered with Destinations. These listen for incoming messages:
MessageObserver myObserver = ...;
destination.setMessageObserver(myObserver);

在CXF中最常用的MessageObserver是ChainInitiationObserver,主要完成如下的功能:接收输入的消息、创建消息的Exchange&PhaseInterceptorChain、开启chains

 

A JAX-WS example

下面这个例子展示了我们用 JAX-WS Endpoint.publish() 发布一个服务的流程:

1、调用Endpoint.publish("http://localhost/service", myService)

2、EndpointImpl用JaxWsServiceFactoryBean创建一个Service,需要用到myService或WSDL

3、根据Endpoint.publish的URL创建一个EndpointInfo

4、EndpointInfo创建一个JaxWsEndpointImpl,包含了JAX-WS端点指定的拦截器

5、JaxWsEndpointImpl开启Binding和Destination的监听

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值