SCA 是由几家国内外知名企业联合制定的,他们成立了一个名为OSOA的组织,SCA
标准目前还在完善阶段,它于
2005
年
11
月发布了
0.9
版本,目前版本已经到了
0.96
。在
0.9
版本中,
SCA
标准就提出了
Java
实现以及
C++
实现标准,而且在以后的版本中,会陆续加入其他的实现标准,也就是说
SCA
并不是只针对某一种语言的,不同语言或者环境之间通过开放的,标准的技术来实现互操作,比如我们常见的WebService等
。
SCA
提出的这套基于
SOA
去构建企业应用的编程模型,它的基础思想就将业务功能构造成一系列的服务,并且能够很好地将这些服务组合起来,达到解决业务需求的目的。在构建这些应用时所用到的服务,不仅包含新建服务,而且可以包括已有的业务应用中的业务功能,也就是说,
SCA
提供了一套针对服务组合和服务创建的模型。
目前来看,虽然有很多标榜自己是基于
SOA
的产品或者框架,但是大部分还是各自为战,而
SCA
的出现有望统一基于
SOA
思想的框架。
Apache
已经在最近完成了
SCA
标准的实现,各位可以去
Apache
的网站看看。国内的一家
Framework
厂商普元也加入到了
OSOA
,并且也宣布会在
2007
年发布一套
SCA
框架的
Framework
。
SCA
具体的应用目前还不太清楚,不过
IBM
的新版本
Websphere
实现了
SCA 0.9
标准,估计慢慢地会让
SCA
得到更广泛的应用。在这片文章里我想简单谈谈
SCA
中的一些重要概念:
Module,Component,ComponentType,Entry Point,External Service
。
Module
Module
是
SCA
构架中重要的组成单元,也是粒度较粗的一个单元。
Module
在
SCA 0.9
以后版本改成了
Composite
,这可能是
OSOA
组织为了更加明确化其含义而进行的一些命名更改。在
SCA 0.96
版本中,
Module
具有了属性,这是为了能够更加方便地注入给
Component
属性值而做的调整。总之在
SCA 0.9
以及后续版本中做了一些改进,但是大体的框架没有发生变化,如图所表示:
它包括了
Component,Entry Point,External Service
,
Wire
等元素,而这些元素互相之间有一定的关联,上图中没有画出
Wire
,因为
Wire
是专门针对
Service Reference
连接
Component
以及
Entry Point
连接到
Component
的描述,在上图中我已经画出了这几种元素之间的关系和连接,所以也就没有必要专门指出
Wire
,如果需要获得更多详细的信息,可以去
DW
或者
Dev2Dev
查看
SCA
规范。
描述
Module
是通过一个
XML
格式文件进行描述的,下面是该
XML
文件的一个大体格式:
<?
xml version="1.0" encoding="ASCII"
?>
<
module
xmlns
=”http://www.osoa.org/xmlns/sca/0.9”
xmlns:v
="http://www.osoa.org/xmlns/sca/values/0.9"
name
="xs:NCName"
>
<
entryPoint
name
="xs:NCName"
multiplicity
="0..1 or 1..1 or 0..n or 1..n"
?
>
*
<
interface
.interface-type
/>
<
binding
.binding-type uri
="xs:anyURI"
/>
+
<
reference
>
wire-target-URI
</
reference
>
</
entryPoint
>
<
component
name
="xs:NCName"
>
*
<
implementation
.implementation-type
/>
<
properties
>
?
<
v:property-name
>
property-value
</
v:property-name
>
+
</
properties
>
<
references
>
?
<
v:reference-name
>
wire-target-URI
</
v:reference-name
>
+
</
references
>
</
component
>
<
externalService
name
="xs:NCName"
>
*
<
interface
.interface-type
/>
+
<
binding
.binding-type uri
="xs:anyURI"
/>
*
</
externalService
>
<
wire
>
*
<
source
.uri
>
wire-source-URI
</
source.uri
>
<
target
.uri
>
wire-target-URI
</
target.uri
>
</
wire
>
</
module
>
ComponentType
和
Component
对于一个
Module
内部来说,
Component
是绝对的主力。
要说起
Component
,
ComponentType
就不得不说。
ComponentType
是一个描述
SCA
中服务的元素,它定义了服务以及服务的接口,以及服务对应的属性和服务引用。
ComponentType
是通过一个后缀名为
.componentType XML
文档来描述的,描述如下:
<
componentType
xmlns
="http://www.osoa.org/xmlns/sca/0.9"
>
<
service
name
="MyValueService"
>
<
interface
.java interface
="services.myvalue.MyValueService"
/>
</
service
>
<
reference
name
="customerService"
>
<
interface
.java interface
="services.customer.CustomerService"
/>
</
reference
>
<
reference
name
="stockQuoteService"
>
<
interface
.java interface
="services.stockquote.StockQuoteService"
/>
</
reference
>
<
property
name
="currency"
type
="xsd:string"
default
="USD"
/>
</
componentType
>
服务的接口目前分为两种:
Java interface
和
WSDL
,这很好理解,
Java interface
就不说了,
WSDL
想必大家也都知道,通过它的描述我们可以得到一个很准确的接口。服务接口是一个可以扩展的属性,我们可以定义出其他不同的接口类型,当然,前提是所使用的
SCA
必须能识别并支持才行。
服务的属性和服务引用和
Spring
的属性以及引用类似。
ComponentType
描述的这些属性和引用,在
SCA Runtime
中实例化服务时,是需要注入的。属性一般对应的是一些简单类型,复杂类型只能是
SDO
和
JAXB
;而引用则是需要对应的也是一个服务,在实例服务的时候,服务所引用的其他服务也需要一起实例化并注入。(注入的前提是该属性或者引用的
requied
属性为
true
,否则
SCA
就不会注入)。
ComponentType
只是描述性地说明一下服务的的接口以及属性,引用,但是具体该服务对应的实现以及属性的值和引用对应的服务是没有给出的。
Component
就是完成上述
ComponentType
没有完成的工作。
我们可以把
ComponentType
想象成一个
Class
,而
Component
是这个
Class
的一个
Instance
。
Component
描述了服务对应的实现,服务实现是通过
implement
元素指定的。这里要注意,
SCA
中,实现是一个比较广的概念,不仅仅是一个简单的
Java
类实现,
Component
所对应的实现和
ComponentType
中所定义的接口一样,是有不同类型的。目前来看,
SCA
规范中给
implement
元素定义了只给出了一个
Java
实现:
JavaImplement
,在
SCA
的一些其他扩展信息中,提出了
BEPL
实现以及
EJB
实现等。
同样,
Component
也描述了
ComponentType
中定义的属性以及引用所对应的值。
Component
的
XML
描述是在
Module
的描述文件中的,下面给出一个片段:
<
component
name
="xs:NCName"
>
*
<
implementation
.implementation-type
/>
<
properties
>
?
<
v:property-name
override
="no or may or must"
?
modulePropertyName
="xs:NCName"
?
>
property-value
</
v:property-name
>
+
</
properties
>
<
references
>
?
<
v:reference-name
>
wire-target-URI
</
v:reference-name
>
+
</
references
>
</
component
>
对于我们刚才提到的服务引用,这里我想罗嗦几句。
服务引用并不是一个调用顺序或者调用关系的描述,它只是指出了服务之间的引用关系,并且能够动态注入而已。很多人认为,
SOA
中服务和服务之间是可以通过业务规则连接起来,然后可以逐个调用,像一个
Flow
一样,其实不然,
SOA
更重要的是关注服务,比如
SCA
就很重视对服务的管理,以及将服务接口和实现解偶,服务和服务之间的连接也只是引用而已,并不是调用顺序。用过
Seebeyond
(比较早的一个面向服务的框架,已经被
SUN
收购)的人都知道,真正去启动服务编排调用的还是
BEPL
。同样
SCA
中之所以提出了
Component
的
BEPL
实现,也是出于对服务编排调用的考虑。
EntryPoint
Module
在
SCA
中是一个粒度较为粗的单元,
Module
和
Module
之间的交互是通过定义在
Module
内部的
Entry Point
和
External Service
进行的,也就是说
Entry Point
是一个
Module
对外提供的接口,而
External Service
是一个
Module
对外访问的出口。
Entry Point
自身是只能定义自己的访问接口,但是真正的具体实现(比如一个
Java Class
),是通过它自身的
Reference
指定的。
Reference
指向的是一个
Component
,这就意味着,该
Entry Point
的调用是直接利用
Component
的实现来完成的。下面是
EntryPoint
的描述片段:
<
entryPoint
name
="MyValueService"
>
<
interface
.java interface
="services.myvalue.MyValueService"
/>
<
binding
.ws port
="http://www.myvalue.org/MyValueService#
wsdl.endpoint(MyValueService/MyValueServiceSOAP)"
/>
<
reference
>
MyValueServiceComponent
</
reference
>
</
entryPoint
>
而一个
Entry Point
既然是对外的接口,那么它就不能像我们访问一个普通
Java
类那么去访问了,所以在对外发布
Entry Point
是需要通过其他的一些辅助技术来完成,比如
Web Service
,
JMS
等,问题在于如何确定该
Entry Point
所对应的这些辅助技术(应该说是某种协议)呢?
SCA
规定,一个
Entry Point
需要指出它的
Binding
,利用
Binding
来确定该
Entry Point
具体是需要通过什么协议来进行发布的。
Binding
Binding
是一个可以扩展的元素,目前
SCA 0.9
中给出了两种
Binding: SCA, Web Service
,不过我们是可以对
Binding
进行扩展的,前提是所使用的
SCA
容器必须支持扩展的
Binding
。
一旦
Entry Point
指明了自己的
Binding
后,
SCA
容器就应该根据它所指定的
Binding
类型对它进行对外发布。比如
Entry Point A
指定了一个
Web Service Binding
,那
SCA
就必须能将这个服务通过
Web Service
的实行发布出去(不要联想到
UDDI
,这里的发布只是说将这个
Entry Point
制作成一个
Web Service
,能让外界通过
Web Service
的访问方式访问到该
Entry Point
)。具体
SCA
如何实现我们不得而知。
广告
本人的一个简单的
SCA Container
实现,可以在uxbalto.googlepages.com得到
相关信息,不过页面没怎么加,东西少得可怜。
External Service
既然理解了
Binding
,那理解
External Service
就容易许多了。先看看描述片段:
<
externalService
name
="CustomerService"
>
<
interface
.java interface
="services.customer.CustomerService"
/>
<
binding
.sca
/>
</
externalService
>
<
externalService
name
="StockQuoteService"
>
<
interface
.java interface
="services.stockquote.StockQuoteService"
/>
<
binding
.ws port
="http://www.stockquote.org/StockQuoteService#
wsdl.endpoint(StockQuoteService/StockQuoteServiceSOAP)"
/>
</
externalService
>
External Service
和
Entry Point
类似,只是一个是对外发布,一个是要去远程访问而已。我们一旦指明了
External Service
的
Binding
后,在访问该
External Service
提供的服务时,我们就会通过指定
Binding
类型对远程发布的服务进行访问。
其实不难看出,由于
SCA
中
Module
和
Module
之间的交互需要通过这么一种远程发布和访问的方式,可以认为
Entry Point
和
External Service
之间是被调用和调用的关系,
Entry Point
发布出去的服务,一般都是由
External Service
访问的。当然,
External Service
不一定非要去访问
SCA
容器中的东西,单独的非
SCA
管理的
Web Service
或者其他什么也可以利用
External Service
去访问的。
结束语
SCA
规范中还有很多没有在文中提起,比如异步调用,服务的
Scope,SubSystem
等,我会在以后的文章中再和大家一起讨论。