SCA的简介
SCA基础
什么是应用程序?一种结论认为它是由一组在一起协同工作的软件组件集合构成。所有的这些软件组件可以
用相同的技术当然也可以由不同的技术创建。它们可以运行在同一机器的同一进程中也可以在不同的进程中,当然也可以跨越多个机器。然而应用程序要正常工作,
需要两样东西:一、有一个创建组件的方式;二、有一个描述这些组件如何交互工作的机制。
SCA就定义了这么一套通用的解决方案。SCA起先是由一组开发厂商(包括BEA、IBM、Oracle、SAP等)创建的,现在归OASIS
所有。SCA规范给出了如何创建组件和如何将这些组件装配成一个完整的应用程序的定义。SCA应用程序中的组件可以由java或其他语言来开发,也可以用
其他技术,比如BPEL或Spring框架技术。不管采用何种组件开发技术,SCA都定义了一套通用装配机制来说明这些组件是如何组装成应用程序的。
Components和composites
每个SCA应用都是由一个或多个组件(component)构成的。在一个简单的应用中,组件(component)也许是运行在单一进程中的
java类,他们通过彼此暴露出来的java接口进行交互。再复杂点的话,java类也许运行在不同的机器上,通过相同的通讯机制来进行交互。再更复杂
些,应用也许包含了一些由java实现的组件,另一些是由C++实现的,甚至用BEPL定义的,并且所有这些组件都广泛分布在各个机器上。所有的这些情况
都存在一个共同点:必须要有一个定义组件(component)并描述他们如何交互的方法。在一个渐增式面向服务的世界里,这些交互都被建模成服务,并清
晰地从提供的功能里分离出了实现细节。
要做这些,SCA定义了组件的通用概念。它也指定了组件(component)是如何装配成更大的构件(composite)的。下图展现了如何由3个SCA的组件(component)组成一个简单的构件(composite)的。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step1.png)
构件(composite)是一个逻辑结构:它的组件能运行在一个单一机器上也能分布在多台机器的多个进程中。一个完整的应用程序也许就由一个
构件(composite)构成,比如上图演示的,或者也可能由若干不同的构件(composite)构成。这些组件也许是用相同的技术开发的,也可能不
是。如图所示,SCA应用也许由非SCA技术的软件访问,比如JSP,Webservice客户端或其他的什么技术。SCA应用程序的组件也能访问数据。
其中一种访问方式就是使用SDO,它(SDO)也许会用到标准的java数据访问技术,例如JDBC或Java5的JPA(Java
Persistence API)。SCA组件也能用JDBC,JPA或其他技术。SCA规范并不强制规定。
非常典型地,SCA构件在一个相关的配置文件中描述,这个配置文件的后缀名为.composite。
该文件为XML格式,配置语言称为SCDL(全称:Service Component Definition Language――服务组件定义语言)。SCDL来描述构件所包含的组件,同时指定他们彼此之间的相关性。以上的例子的SCDL配置如下:
<composite name="ExampleComposite" ...>
<component name="Component1">
...
</component>
<component name="Component2">
...
</component>
<component name="Component3">
...
</component>
</composite>
组件和构件是SCA应用的基本元素。他们都包含在一个更大的结构中,该结构称为“域”(domain)。所以要理解SOA就要理解domain。
域
关于SCA创建者的一个隐式的假设是在给定的环境会安装一组SCA产品,一般来说某个产商会提供运行时环境。比如,假设一个大公司的一个部门选
择了某个特定的SCA提供商。这个部门很可能就要把他们所选定的SCA提供商的SCA运行时环境安装到机器里。这不是不切实际的假想,因为它反映出公司是
如何购买和安装J2EE产品的。这些SCA运行时环境也许由相同的组内成员来管理。那么这整套系统――包括厂商的运行时技术和管理――就构成了一个最简单
的“域”这个概念。
域在SCA中是非常重要的概念。来看看为什么,虽然我们知道SCA允许创建分布式应用,但它并没完全定义在不同机器上的组件是如何交互的。所
以,这些组件之间的通讯能够用不同的产品来实现。(在下面SCA的实现这节描述了,SCA运行时允许第三方创建容器,这个容器能挂载到支持特定技术的运行
时环境中,比如BEPL 技术)。
域能包含一个或多个构件,每个构件都包含了多个运行在一台或多台机器上的一个或多个进程中的组件。下图给出了一个例子:
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step2.png)
这里展示的“域”包含了三个组件三个构件。图中上半部所显示的构件由五个分布在两台机子中跨越了三个进程的组件构成。图中下半部所显示的另外两
个构件,都运行在一台机子上,分布在三个独立的进程中。组件与组件之间,不管是在同一个进程中,或进程间还是机器间的通讯方式都会因每个不同的SCA厂商
而定义不同。但不管怎么定义,构件都不能跨越“域”的界限。
多厂商的关于创建分布式应用的方式没有固定的定义,同时应用中的组件交互的方式也没有定义。理解了这个,我们就意识到SCA创建者的主要目标是
代码的移植性和开发者开发方式不会受到不同SCA实现的影响。同时创建能跨越“域”的构件也许有一天能成为可能的,不能跨越“域”的规定并不是SCA第一
版的目标。限制组件在一个单一的域中允许更有效的优化。在一个域中,SCA开发者的工作是相当简单的,比如,能避免由于多厂商应用配置的复杂性。
不要被搞糊涂了。虽然SCA 构件运行在单一的厂商环境中,它还是可以与它自己域外部的应用程序进行通讯的。SCA组件能通过使用交互性协议比如Webservice来开放自己的可访问性接口。如下图:
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step3.png)
这个例子展示了两个SCA域,每个域都在两台机器上。一个域使用了X厂商的SCA运行时环境,而另一个用了Y厂商的SCA运行时环境。每个域内
的这些组件和构件彼此之间的通讯都是各自厂商的方式,SCA并没有强制交互应该如何进行。要进行域之间的通讯或与非SOA应用的通讯,组件都允许通过
Webservice或其他一致的交互机制。事实上,SCA应用与其他的处于不同域内的SCA应用的交互看上去就跟与非SCA应用的交互一样;在域外
SCA是不可见的。
理解组件(component)
组件是SCA应用程序的原子,因此SCA组件行为上要保持一致性以便他们能装配。理解SCA要从理解这些基础的应用程序构件块开始。
以SCA的说法,组件是一个实现的实例,该实现是可以配置的。实现是提供组件功能的代码,比如可以是java类或BPEL过程
(process)。用SCDL表达的配置信息定义了组件是如何与外部世界交互的。理论上来说,SCA组件能够用任何一种技术实现。当然不管是用什么技
术,每个组件还是要依赖一些通用抽象集的,包括服务,引用,属性和绑定,用这些来描述自身与外部世界的交互方式。这一节就描述上面提到的通用抽象集。
服务、引用和属性
从外部来看,SCA组件是一个简单的东西。然而不管是用什么技术创建的组件,他都有下图所示的基础部分。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step4.png)
每个组件一般都实现一些业务逻辑,并将他们做为一个或多个服务公布出去。图中是用绿色箭头表示的服务,提供了一些能让组件客户程序访问的操作。
服务如何来描述则依赖于实现组件所采用的技术。比如,Java实现的组件也许用Java接口来描述服务,而用BPEL实现的组件也许用WSDL(全
称:Web Services Description Language――Web服务描述语言)来描述服务。
在给自己的客户提供服务的时候,组件也许还会依赖于同一域中其他组件或域外软件所提供的服务。为了描述这个,组件能通过引用定位它所依赖的服务。上图紫色箭头,每个引用都定义了一个包含当前组件需要调用的操作的接口。
这些服务和引用的核心概念是值得斟酌一番的。用服务去建模组件提供给客户的功能越来越普遍了。最近,显式地定义引用也更流行了,它有些优势。首
先,正式地表达了组件的依赖关系能帮助开发者认清代码间的关系,开发者喜欢它。显式的引用还允许依赖注入(DI)。DI这个苦涩的短语有一个简单的含义:
改变原来要求开发者自己写定位一个组件所依赖的服务的代码,现在SCA运行时能定位该服务了。少写代码是很好的,因为这样可以不用修改任何lookup的
代码而更容易地实现从一个运行环境到另一个运行环境的移植。
除了服务和引用外,组件还能定义一个或多个属性。每个属性都包含一个值,该值在组件初始化的时候可以从SCDL配置文件中读取。比如,组件会通过属性得知自己运行的环境,从而定制自己的行为。
绑定
服务和引用都是用于组件通讯的。通过设计,组件根本不需清楚通讯是怎么进行的。这个就是绑定所做的工作。下图给出了SCA中的绑定的好处。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step5.png)
绑定确切地说明了SCA组件和其他软体之间的通讯是如何来进行的。根据通讯对象的不同,组件可能有也可能没有显式地指定绑定。如图所示,同一个
域内的与其他组件通讯的组件,不管他们是在不同的进程中,还是在不同的机器上,都不需要任何显式地指定绑定。运行时环境会决定会用到什么绑定,从而把开发
者从这些繁杂的事务中解脱出来。
然而,为了与域外通讯,不管是不是运行在某个其他域的SCA应用,组件的创建者(也许会是部署组件的人)必须指定通讯的绑定。每个绑定都定义了用于与服务或引用通讯的特定协议。每个服务或引用能有多种绑定机制,允许通过不同的方式与不同的远程软体进行通讯。
因为绑定把组件的通讯从组件的功能中分离出来,所以他们让组件的业务逻辑与通讯细节剥离开来。这是源自试图将通讯和功能混合在一起的老技术,简化和应用的设计和开发。
一个例子:SCA的JAVA组件模型
SCA组件的基本抽象很简单:服务,引用,属性和绑定。然而,抽象还不够。必须有一种告诉我们如何去抽象这些从而创建出组件的方法。
一些已有的技术已经和SCA组件的抽象很匹配了。比如,Spring框架提供了对服务、引用和属性的显式支持,所以可以将这些直接映射到SCA
的理念。因此,利用Spring创建SCA组件的规范定义内容并不多。类似的BPEL也对SCA组件的抽象提供了某些内置的支持。例如,BEPL的
Partnerlink(伙伴服务)这个概念就能映射成服务和引用。而要求使用属性的扩展,通过使用BPEL来创建组件的SCA规范也非常短的内容,不超
过12张纸的内容。
即使BEPL和Spring都是创建SCA组件的可行候选技术,但都不是以SCA的理念来创建的。那么为什么不设计一个用于创建SCA组件的基础编程模型呢?这就是SCA的Java组件模型做的工作。下一节将描述SCA组件是如何使用这种新的编程模型来创建的。
在此之前,为什么SCA的创建者要选择去发明另一个新的java编程模型呢,这个问题值得我们去思考。一个主要的动机就是面向服务方法的需要。
当前的Java业务逻辑编程模型,比如EJB,并不是将服务看做是一种基础设施的。因此,Java EE
5的技术完全没有与SCA的组件理念匹配上。同时也因为绑定将通讯细节从业务逻辑中分离出来,所以基于SCA的Java组件模型支持各种不同的通讯方式。
依次,使用SCA的新组件模型能明显简化开发。
定义服务
不象老的J2EE
技术,SCA的Java编程模型依赖于annotation而不依赖于API调用。这种方式使得创建基础服务非常容易。事实上,对于一个给本地客户提供的
服务,根本没有什么要求,一个Java接口和类就行了。然而对于远程客户访问的服务必须象下图那样指明相应的annotation的接口
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface AS
{
int add(int a, int b);
int subtract(int a, int b);
}
public interface MD
{
int multiply(int a, int b);
int divide(int a, int b);
}
public class Calculator implements AS, MD
{
public int add(int a, int b)
{
return a + b;
}
public int subtract(int a, int b)
{
return a - b;
}
public int multiply(int a, int b)
{
return a * b;
}
public int divide(int a, int b)
{
if (b == 0)
{
throw new IllegalArgumentException();
} else { return a / b; }
}
}
这个例子代码的开头导入了标准的SCA包。然后使用了annotation(注释),@Remotable来
指定AS接口所提供的服务可以被远程客户访问。当然还要在SCDL配置中定义这个组件。后面会讲到,在Java代码中只要这个annotation(注
释)就够了。SCA运行时会去做基础工作保证远程客户的访问。作为与服务在同一个域的客户端来说,所使用的通讯协议并不是强制规定的。每个SCA运行时可
以自己选择。因为要允许跨越厂商的交互,所有的远程接口必须用WSDL来描述,也就是隐含地说明了通过SOAP协议来访问。
两个接口都是用同一个类实现的,这里就是Calculator类。因为他们都在接口定义中用@Remotable表识了,所以Add和Subtract方法即能被远程又能被本地客户访问。Multiply和Divide方法,定义在一个没有用@Remotable表识的接口中,所以只能被运行在同一个进程的客户端访问。
定义引用
服务使得组件描述了它自身对外部边界所提供的功能。引用则表达了组件需要外界哪些服务。SCA的Java编程模型中,引用是用@Reference标签来指定的。比如,假设这个示范的计数器依赖与追踪使用的监控服务,那么服务就如下这么定义:
@Reference
protected MonitorService monitorService;
MonitorService是一个接口,用平常一样的方式就能调用这个组件的服务。要调用usageCount方法,只要用monitorService.usageCount(x);就可以了。
组件不需要去创建一个实现了MonitorService接口的类的实例,运行时环境会自动去定位提供接口服务的组件,并设置monitorService的值。原来要开发者去写查找服务的代码,现在这个责任交给运行时环境了(这种方式称为依赖注入,有时也称为控制反转)。
至于运行时环境如何查找服务实例的细节留给每个SCA运行时的创建者去解决。但是,别期望引用会自动地连接到在另一个SCA域中的组件所提供的服务。在一个厂商的环境中,使用引用是可以简化开发的。
定义属性
属性是非常简单的概念,在java中使用属性也非常简单。这里是个例子:
@Property
protected String region;
象引用和远程服务一样,属性也用annotation:@Property来
表识。该annotation是java类中的域或setter方法。属性就是能从某个构件所包含的某个组件的SCDL配置文件中读取出来的值。属性也可
以更复杂些。他们不仅仅是字符串或整数或其他的简单数据类型。然而不管他们简单不简单,目标都是一个:提供一种能在运行时去配置组件的方式。
定义绑定
如前所述,绑定决定了组件是如何与它所在域的外部是如何通讯的。绑定能分配给服务和引用。每个绑定都指定了特定的协
议。为了证明绑定为什么如此有用,我们来考虑应用程序如何在Java
EE5和J2EE的前技术中是怎么使用不同协议的。如下图所示,每个协议都由不同的技术提供,所以每个协议都有自己的应用编程接口(API)。比如,使用
基于HTTP协议的SOAP,就意味着是建立在JAX-WS或J2EE 1.4里的JAX-RPC,当使用队列消息协议就要求用JMS(Java
Message
Service)。这就强制要求开发者去学习不同的API,使用完全不同的编程模型,使用不同的协议。这也将通讯的代码混杂在业务逻辑中,加重了开发者的
负担。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step6.png)
SCA提供了简单的编程环境。比起用不同的API将不同的协议封装进不同的技术,SCA允许每个远程服务和每个引用都利用绑定来指定它所支持的协议。就应用的编程模型看来,并不关心所用的协议,如下图。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step7.png)
比如,想通过SOAP协议来访问,SCA服务可以使用Web
Services绑定,而想通过队列消息队列协议则使用JMS绑定。同样地,EJB的会话Bean绑定允许使用IIOP(Internet
Inter-ORB Protocol)协议来访问会话Bean。每个SCA运行时还允许提供SCA绑定。该绑定所使用的协议并不指定。SCA绑定只能用于服务和它的客户端都处于同一个域中的情况下。因为每个厂商都想让架构在自己产品的应用程序性能能越出色越好,所以一般来说,绑定都会选用二进制协议。当然,这并不是强制规定的,SCA运行时可以在不同的情况下使用不同的协议,当然这些协议都应该在SCA绑定的支持范围内的。
SCA Java组件模型1.0版没有直接指定绑定的定义。对于域内通讯,是由运行时环境来决定,或在组件的SCDL配置文件中显式设置的。这里有个组件服务的绑定配置的例子:
<binding.ws uri="http://www.qwickbank.com/services/serviceA"/>
这个例子中的binding元素说明了两个东西:绑定所使用的协议是什么,还有就是用这种协议到哪里可以访问到服务。元素名后的.ws指明是Web service的绑定。Uri这个元素属性给出了访问服务的URL地址。其他的绑定也用类似的方式来指定。比如binding.jms元素指定JMS绑定,而binding.ejb指定EJB会话Bean绑定。
定义组件的其他方面
如前面所展示的@Remotable属性一样,SCA Java组件模型还定义了其他一些内容。现将重要的内容列出如下:
@OneWay,指定该操作不需要等待响应就可以立即返回。
@Scope,控制组件的生命周期。比如,组件可以是conversational,就是意味着在方法调用之间来维护状态,如果是stateless则表示方法调用之间无状态要维护。
@Callback,定义回调接口。这支持组件之间使用SCA双向接口来进行双路通讯。
不是所有的属性对于绑定都是有用的。比如, conversational选项的@Scope属性只能用于能传输会话信息的协议,例如可以使用WS-ReliableMessaging来做SOAP的绑定。不管任何的编程环境,SCA开发者都必须理解技术,并正确使用。
配置组件
不管是用SCA的Java组件模型来实现还是用其他的技术来实现,每个SCA组件都依赖于SCDL配置文件中所属的构件相关的配置信息。前面已经演示了每个组件是使用component元素来进行定义的,组件包含在composite元素中。组件必须确切地指出是否与处于同一个SCA域的组件进行通讯还是与域外的软体进行通讯。一般情况下,组件仅仅和处于同一域的其他组件进行交互,Component元素非常简洁。前面用到的Claculator类,他的元素就象下面所示:
<component name="Component1">
<implementation.java class="services.examples.Calculator"/>
<property name="region">
Europe
</property>
</component>
与所有的component元素一样,分配了一个组件名并提供了相应的子元素。首先,implementation.java,指明了组件是用SCA的Java组件模型实现的,然后指定了java的实现类。第二个元素,property定义了组件的属性值。当组件运行的时候,不管值是什么都会读入到组件的region域里去。注意,该组件相关的服务和引用都不需要在此描述。运行时环境会通过introspection(自省)技术发现这些,不要求显式地列出这些。 由于通讯发生在同一个域内,所以运行时环境会选择使用哪个绑定,而不需要在此指定。
然而,假如Claculator类和域的外部进行通讯,将会更复杂些。设想下远程服务和引用都能连接到组件域的外部。这种情况,component元素就要象下面这么来配置了:
<component name="Component1">
<implementation.java class="services.examples.Calculator"/> <service name="AS">
<binding.ws uri="http://www.qwickbank.com/services/serviceA"/> </service>
<reference name="MonitorService">
<binding.ws uri="http://www.qwickbank.com/services/serviceM"/> </reference>
<property name="region">
Europe
</property>
</component>
当然,组件的描述还是以implementation.java元素开头指示组件的实现技术和如何找到实现的类,还有以property元素结尾。中间用显式的service和reference元
素来代表组件定义的远程服务和引用。远程服务和引用都指定用Web
service来绑定,并给出了URL。因为组件和域外部的软体进行通讯,运行时环境不能选择绑定。组件显式地指定互操作的绑定。由SCA运行时环境从
Java接口生成WSDL接口,以便能通过SOAP来访问该服务,然后完成其他必须的工作让组件能通过Web service来进行通讯。
如这里所说,Calculator组件是用SCA Java组件模型实现的。假如用其他的技术显示,他的SCDL配置定义也不需要变很多。如果是用BEPL来实现的组件与自身同一个域的组件进行交互的话,配置如下:
<component name="Component1">
<implementation.bpel process="ExampleProcess"/>
<property name="region">
Europe
</property>
</component>
和前面的implementation.java元素不一样,BEPL组件用了implementation.bpel元素,用了一个process而不用java类。其他不需要改变了。当然运行时环境行为会有所不同,而去执行BEPL组件,SCA的抽象组件定义还是和原来一样,只要求对SCDL配置文件进行小的改动。类似的,用Spring框架实现的组件要用implementaion.spring元素指定,用SCA的C++组件模型要指定implementation.cpp。这个方法允许构件的嵌套,而不用关心里面每个组件具体是用什么技术实现的。
理解构件
如果说组件是SCA的原子,那么构件就是分子。构件将组件组装成有用的集合,而构件还能进一步组合。这种以构件块的
方式去创建应用有很明显的好处。比如,提供一个定义良好的抽象集能帮助人们在创建应用时更加清晰地思考应用应该如何设计。保证用不同技术实现的抽象的一致
性使得可以非常容易地使用不用的语言和运行时环境来创建应用程序。回忆下,构件里的组件可能运行在同一台机子的同一个进程中或不同的进程中,也可能在不同
的机子的不同进程中。所有这些情况下,有某种方法把整个应用作为一个单元来部署都是有益的。组件提供了离散的、定义良好的服务还有图形工具,能针对特定的
问题来装配或重新装配各种组件。这些将简化开发者的工作,甚至不需要什么技术背景的人也可以通过装配已有的组件来创建应用。
要达到这些目标要求把构件中组件与组件是如何相关联的定义下来。这些会在SCA的装配模型规范中描述。这节让我们近距离看看构件是如何装配的。
Wires and Promotion
和以往一样,先从图开始。下图显示了三个组件,每个都由服务和引用所组成。这三个组件都处于同一个构件中。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step8.png)
如图所示,一个组件的引用是通过wire来连接到另一个组件所提供的服务的。Wire是引用和满足引用需求的服务之间关系的抽象表达。确切地
说,wire提供了什么种类的通讯机制是可变的,具体依赖于所使用的特定的运行时环境。不管是在单一机器的单一进程,还是跨机器的多进程的情况,wire
都能表达这种关联关系。
就如组件可以公布出服务一样,构件也能公布出一个或多个服务。服务其实是由构件中的组件实现的。要使得服务能被外界访问,构件的创建者要能提升
(promote)这些服务。这个例子中,由组件1所提供的A服务被提升成了构件向外界提供的服务。类似的,组件定义的0、1或多个引用也能提升到构件的
层次。这里的T和U就提升到了构件级。
配置构件
构件中的所有关系都能在SCDL配置文件中表达。例子如下:
<composite name="ThreeComponents" autowire="true"...>
<component name="Component1">
<implementation.bpel process="Process1"/>
</component>
<component name="Component2">
<implementation.java class="services.examples.class2"/> </component>
<component name="Component3">
<implementation.java class="services.examples.class3"/> </component>
<service name=”A” promote=“Component1/A”
<binding.ws/>
<service/>
<reference name=”T” promote=“Component2/T”/>
<reference name=”U” promote=“Component3/U”/>
</composite>
跟所有的SCDL配置一样,composite元素里封装了所有的内容。在这个例子中,composite元素的autowire属
性设置为true。这表明SCA运行时应该自动去连接组件中定义的服务和引用。要完成这个功能,运行时环境会在组件所公布的服务和应用之间查找相匹配的。
服务必须提供引用要求的接口,允许使用兼容性的绑定,当然也许还有更多的要求。尽管图中没有显示出来,但还是有可能用wire元素来显式定义组件与组件之
间的wire关系的。
下一个出现的component元素描述了组件中的三个组件。第一个组件是用implementation.bpel元素来表示是用BEPL实现的。另外两个组件是用implementaion.java来表示是用SCA 的Java组件模型实现的。尽管图里给出了每个组件都提供了服务和引用,但在component元素中没有一个是显式指定的。反正运行时环境会发现他们并选择恰当的绑定机制。
这三个组件都定义完后,构件自身提供的服务是用service元素来指定的。这个例子将component 1的A服务提升为构件的服务,就意味着该服务可以被构件域的外部来访问,所以它定义了显式的Web service绑定。如法炮制,两个reference元素都提升为构件的引用。这个例子中假定引用的其他的组件都在一个域中,所以绑定不需要特别指定。
构件现代的企业应用有着不可避免的复杂性。有很多技术来实现业务逻辑,比如BPEL,Spring还有SCA的Java组件模型,复杂度递增。SCA构件的主要目标就是提供一种统一的方式,将不同的技术实现组装成应用,从而使得这些多样性更具有可管理性。
使用策略
分布式应用各部分之间的交互是复杂的。一种使得这些工作更具有可管理性的方式就是让开发者可以使用策略(policies)来表明他们的意图,并能完成实现这个意图的目标。SCA定义了policy framework来完成这些工作。
这个框架定义了两大块:
交互策略:可以修改组件之间的交互。比如,加入安全或可靠性信息传输的策略要求。交互策略可以应用到绑定上。
实现策略:修改组件的行为。比如要求一个组件必须运行在一个事务中(尽管SCA的初始1.0版本并没定义事务策略)。
和SCA里的其他内容一样,策略能在SCDL配置文件中声明。对于SCA的Java组件,能通过对接口、方法或其他的什么使用annotaion来声明策略。比如@Confidentiality这个annotation指定了通讯必须是可信任的(就是指加密),@Authentication则指定了必须经过认证。
那么这些annotation是什么含义呢?这个答案取决于这些策略是如何定义的。要定义策略,SCA在每个域中设置了一个管理员的角色。管理
员通过指定意图和策略集来指定特定的策略。比如,一个服务的绑定能有一个相关的描述交互策略的策略集,引用的绑定能有一个描述交互策略的策略集。当
wire在他们直接创建的时候,这些策略集就匹配了,由这些策略交集来决定通讯所使用的策略。
SCA没有定义一个域内的策略是如何描述的――并不强制一种策略语言――每个厂商都可以自由地使用自己的语言方式。但是,域与域间的通讯则可能
要用web
service,而策略则用WS-Policy以厂商中立的方式来描述。因为策略是在域的级别来定义的,所以有可能策略的需求有时会影响到域边界。如前所
述,域是由单一厂商提供和由单一组管理的SCA运行时环境的集合。这种环境下,一个组织的不同部门可能需要不同的策略。想象下,同一公司的两个部门使用同
一个厂商的SCA产品,但有不同的安全需求。针对这个问题,公司可能会创建两个独立的SCA域,每个都有不同的安全策略。
把这些知识融合在一块:举一个SCA的例子
SCA定义了一套创建应用程序的通用框架。最好的办法就是通过例证一个具有代表性的例子来把握它。下图显示了用SCA怎么来创建一个应用。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step9.png)
在这个例子中,客户端是JSP页面。JSP调用了作为样例构件中一部分的SCA组件提供的服务A,该组件是用BEPL技术实现的,并且该服务升级到构件级别,以便构件外能访问,当然这些都是通过SCDL配置文件中表达的。
BEPL组件包含了另两个服务的引用,P和Q。服务P是由SCA的Java组件模型实现的组件所提供的,该组件处于另一个SCA域的某个构件
中。相应地,与该组件的通讯都是用Web
service(或者也许是其他某种交互协议)。服务Q是由处于同一构件中的另一个用Spring技术实现的组件提供的。BPEL组件和Spring组件
之间的交互依靠于指定域的SCA绑定机制,并可以使用任何指定的策略。
然而,Spring组件实现了服务Q,它又依赖于服务X。这个服务是由使用微软的WCF(Windows Communication
Foundation)技术创建的应用所提供的。因为不是基于SCA的,所以使用Web
service进行通讯。这里要反复重申与非SCA的服务通讯就如同与处于另一个域的基于SCA的服务进行通讯,内部实现细节是封装好的,所以就以往常的
Web service的方式交互。最后,Spring组件访问数据库,如图所示。这种访问方式可以使用SDO或其他某种方式。
实现SCA
SCA规范本质上并没有谈到这个技术应该如何实现。存在各种开源的实现,象Tuscany和Fabric3,各家厂商都有自己的实现方式。尽管如此,下图给出了一个建立SCA运行时环境的一般方法。
![](http://p.blog.csdn.net/images/p_blog_csdn_net/oracle1000g/step10.png)
这里显示的,SCA运行时环境也许会提供若干个容器,对各个组件提供技术支持。SCDL配置文件的implementation元
素告诉运行时该构件需要什么类型的容器,还告诉运行时如何起查找构件中组件的实现。在这个例子里,SCDL配置文件就指明了需要实现了SCA
Java组件模型、BEPL和Spring的容器。SCA运行时环境提供了所有绑定机制,可以允许利用任何技术创建的组件可以使用任何一种可用的绑定技
术。运行时也定义了所有组件与组件之间的通讯,而不关心这些组件是如何来实现的。
尽管不要求,但SCA的实现还是公开了运行时与容器之间接口。这样允许第三方创建自己的容器,能使得SCA运行时更具有扩展性。这种接口的一种
候选方案就是JBI(Java Business Integration),一个由JCP(Java Community
Process)制定的规范。JBI只支持基于Java的技术,如果用于C++容器就有问题,它不能获得主要Java厂商的广泛支持。但还是有些厂商选则
使用C++,而没有用Tuscany或Fabric3来实现JBI。
创建SCA运行时的缔造者也可能使用OSGi。它是由多个厂商组成的工作组制定的,比起JBI提供了更多主要SCA厂商的支持。OSGi定义了
如何将代码打包成bundles,它也是只支持Java的,一些SCA 运行时的设计者将要添加的新的绑定做为OSGi bundle来进行扩展。
运行时和容器当然都是必须的,但也只是开发者的工具而已。SCA工具能由多个不同的厂商提供,现在也已经有一个开源工具项目了。SOA
Tools Platform
Project,他的目标之一就是要为Eclipse提供一个基于SCA的开发工具。随着越来越多的技术,更多的开发者将通过各种工具来认识SCA。
结论
不同的人看SCA的角度不同。规范提供了很多种候选方案,所以当有人说”SCA”的时候,他可能是指这些规范所定义的所有内容。类似的,不同的
厂商也强调着SCA的各个不同的方面。某个厂商也许为SCA的装配环节和新的Java组件编程模型提供支持,而未提供C++版本。另一个厂商也许只对
SCA装配提供支持,完全忽略了新的Java和C++的编程模型。同时因为规范能允许厂商自我扩展,所以每个厂商都会在各自的SCA产品中提供某些定制服
务。
然而,SCA是一个没有争议并很有趣的技术。通过对老技术,比如EJB和JAX-WS,提供一个替代方案,就能为基于服务开发提供创建Java业务逻辑的新方法。通过为用各种技术实现的组件提供装配机制,就能满足各种不同环境需求。
当然也有反对SCA的厂商群。还有很多问题――比如,一致性是什么意思,为什么SCA提供这么多种侯选方案?但该技术的潜力还是很明显的。事实很清楚地摆在面前:只要是关心应用开发的未来的人都应该会对SCA感兴趣。
转自:http://blog.csdn.net/oracle1000g/archive/2007/12/12/1930826.aspx
转自:http://blog.csdn.net/oracle1000g/archive/2007/12/12/1930826.aspx