概述
SCA Java运行时由core和extension组成。Core本质上来说是一个多VM的wiring引擎。该引擎使用IOC(控制反转)和DI(依赖注入)原则来连接组件。
Core
Core在性能方面是简单而有限的。它将功能单元连接在一起,并提供可以和extension交互的SPI机制。例如象服务发现,可靠性,对传输协议的支持等特性都是通过extension来做的。
Extension
Extension增强SCA运行时的功能。Extesion类型不是固定的。而core则是通过提供对extension模块开放支持来使得设计尽量灵活。
- 组件实现类型,例如:Spring, Groovy 和Javascript
- 绑定类型,比如:Axis, CXF ,AMQP ,ActiveMQ, JXTA
- 数据绑定类型,比如:JAXB, SDO ,XmlBean
- 接口绑定类型,比如:WSDL, Java
关于如何实现一个extension的详细信息可以在Extensions Guide中查看。
运行时
Core是设计得可以嵌入于许多不同的主机环境下的。例如,core也许用于OSGI容器、单独的运行时环境、serlvet引擎或J2EE应用服务器中。运行时的性能根据主机环境不同而不同。
Java SCA运行时的高层概述:
下图是由关键的模块/包组成的SCA运行时高层视图
1、 SCA Spec API:由SCA Java Client and Implementation定义的API
2、 API:扩展了SCA Spec API的Tuscany API
3、 Core:运行时实现和SPI扩展机制
4、 Extension:
1. Component(英文原版有错误) implementation – 扩展语言支持:例如 BPEL,Python,C++,Ruby等
2. Binding – 扩展协议支持:例如 Axis2, CXF等
3. Interface Binding – 扩展服务定义类型:比如SWDL, Java等
4. Databinding – 扩展数据支持:比如SDO, JAXB等
5、 Host platforms:Tuscany运行时的主机环境
<!--[if !vml]--><!--[endif]-->
内部高层视图
参考下图:
<!--[if !vml]--><!--[endif]-->
引导过程
引导过程是由主机环境控制的。默认的实现是DefaultBootstrapper。运行时由某个成型的SCA Assembly XML文件序列化而来并处理服务装配。
- 装载阶段处理SCDL并创建一个内存模型处理相应的运行时工件(例如组件componet,服务service,引用reference)
- 连接阶段将对服务的引用连接起来
装配模型
SCA装配模型在Tuscany中是用一系列接口表示的。如下是些关键的元素。
- SCA component 是配置化的SCA实现的实例,它可以提供服务或消费服务。
- SCA service用于声明实现的可以被外部访问的服务
- SCA reference用于表示该实现对某些其他实现所提供的服务的依赖。该依赖的服务可以通过配置来指定。
Implementation是用于描述软件技术的概念,例如在面向服务的应用中实现了一个或多个服务的Java 类,BEPL,XSLT转换,C++类。SCA composite也是implementaion。
ComponentType涉及实现的可配置的方面。
Interface定义了一个或多个业务功能。这些业务功能通过Service提供,通过Reference让其他组件使用。服务是由实现的接口来定义的。现在SCA支持两种接口类型系统:Java接口、SWDL portType
SCA composite是SCA域中的compositon的基础单元。SCA Composite是组件的装配,服务、应用和wire都互相连接。
SCA wire将服务引用连接到服务上。
Binding是被服务和引用所使用的。引用使用绑定来描述访问机制,该机制用于访问连接的服务。服务使用绑定来描述客户程序调用服务的访问机制。
Property是考虑到有的实现配置需要显式地设置数据值。该数据值由组件提供,当然也可能来源于容器composite的属性。
<!--[if !vml]--><!--[endif]-->
Contribution
Tuscany运行时提供了一个框架来支持SCA的contribution。框架可以通过下列的两个扩展点来扩展:
PackageProcessorExtensionPoint:它用于处理不同的包装格式或归档的扩展,可以是目录、Jar、OSGI bundle、EAR、War或Zip。
ArtifactProcessorExtensionPoint:它用于处理特定工件类型的扩展,可以是SWDL,XSD,composite,java类后BEPL。
<!--[if !vml]--><!--[endif]-->
<!--[if !supportLists]-->l
<!--[endif]-->包处理器会扫描安装了的contribution,并产生需要处理的工件列表。当前有支持文件夹/文件系统和
Jar contribution包。为了让contribution服务有效,包处理器要注册自己给包处理extension 。
<!--[if !supportLists]-->l
<!--[endif]-->工件处理器用于处理contribution上的每个有效的工件。为了让contribution服务有效,工
件处理器要注册自己给工件处理extension 。对于每个工件,工件处理器分两个阶段被调用。
<!--[if
!supportLists]-->?
<!--[endif]-->读阶段:这里是你读取工件(可以是一个文档、XML元素或类等等)的地方,组装描述工件的模型并返回它。SCA
contribution服务在所有注册了工件处理器的工件上调用ArtifactProcessor.read()。假如你的模型引用了其他的模型,
不需要立刻装载那些模型,你只需要保持描述引用的信息,在resolve阶段,你将会把该信息转换成指向被引用模型的指针。注意:你没有必要在这个时刻完
全读取并装载模型,你可以在以后来完成这些工作。
<!--[if !supportLists]-->?
<!--[endif]-->解析阶段:这个阶段让你有机会解析对其他模型的引用。这个时刻,SCA
contribution中所有的描述工件的模型都已经读取,并注册了工件解析器,准备被解析。
<!--[if !supportLists]-->l <!--[endif]-->所有可部署的composite应该在现在准备部署到SCA域中。
包处理器会扫描安装了的contribution,并产生需要处理的工件列表。当前有支持文件夹/文件系统和Jar contribution包。为了让contribution服务有效,包处理器要注册自己给包处理extension 。
工件处理器用于处理contribution上的每个有效的工件。为了让contribution服务有效,工件处理器要注册自己给工件处理extension 。对于每个工件,工件处理器分两个阶段被调用。
?
读阶段:这里是你读取工件(可以是一个文档、XML元素或类等等)的地方,组装描述工件的模型并返回它。SCA contribution服务在所有注册
了工件处理器的工件上调用ArtifactProcessor.read()。假如你的模型引用了其他的模型,不需要立刻装载那些模型,你只需要保持描述
引用的信息,在resolve阶段,你将会把该信息转换成指向被引用模型的指针。注意:你没有必要在这个时刻完全读取并装载模型,你可以在以后来完成这些
工作。
? 解析阶段:这个阶段让你有机会解析对其他模型的引用。这个时刻,SCA contribution中所有的描述工件的模型都已经读取,并注册了工件解析器,准备被解析。
所有可部署的composite应该在现在准备部署到SCA域中。
实现扩展
实现扩展负责实现类型的支持,例如Java,Script和BEPL
绑定扩展
绑定扩展负责对绑定类型进行支持,例如web service,JMS,JSON-RPC和RMI
接口扩展
接口扩展负责接口类型的扩展,例如Java接口和WSDL 1.1 portType
数据绑定扩展
请看我翻译的Tuscany数据绑定指南
Composite 激化
在composite完整地配置后,就能在SCA域中激活它。Tuscany运行时用以下步骤激化composite:
1、 构建composite:这个阶段,composite模型更进一步地正规化来方便运行时的交互。元数据在service/reference提升后统一化了。根据这个扁平模型,我们可以获取所有的组件级信息。
2、 配置composite:这个阶段,composite层次结构用于导航组件实现的配置信息。引用绑定和服务通过提供者工厂来创建运行时组件以及外部服务之间的连接。
3、
创建运行时连接(wire):这个阶段,为组件引用和组件服务以选定的绑定形式创建运行时连接。运行时连接是一个调用链的集合。这些调用链按照操作来分成
区。每个调用链都由一系列的调用器和拦截器构成。调用器提供到绑定协议和实现技术的逻辑调用。拦截器是特定类型的调用器,为调用它提供了附加的功能,比如
数据传输和事务控制。对于一个组件引用,我们创建运行时连接(wire)来描述以选定绑定的形式对外的调用。对于组件服务,我们创建运行时连接
(wire)来描述对实现的对内调用。回调连接(callback wire)能附加到组件服务上来描述来自服务的一个回调调用。
4、
启动composite:这个阶段,由ImplementationProvider、ReferenceBindingProvider和
ServiceBindingProvider定义的start()回调方法会被调用。最终,组件,组件引用和组件服务被初始化而服务于组件的交互。服务
监听器会启动,从而接受来自绑定层(binding layer)的入内请求。
<!--[if !vml]--><!--[endif]-->
<!--[if !vml]--><!--[endif]-->
调用概述
调用会被分发到WireInvocationHandler
WireInvocationHandler查找正确的InvocationChain
然后创建一个消息,设置有效负载,设置TargetInvoker,并传递消息给下层链
当消息到达链的末端,TargetInvoker会被调用,现在轮到TargetInvoker负责叫调用分发到目标
存储在outbound边界上的TargetInvoker当连接源的作用域值等于或小于目标的作用域值时,允许缓存目标实例。运行时环境通过
Inboundwire和Outboundwire提供组件。调用链附着于组件连接(wire)中,因此是无状态的。所以调用链可以具有动态行为,例如新
拦截器的介入和重新连接。
装载SCA装配
工件处理器用于处理contribution上的每个有效的工件。为了让contribution服务有效,工件处理器要注册自己给工件处理extension 。对于每个工件,工件处理器分两个阶段被调用。
?
读阶段:这里是你读取工件(可以是一个文档、XML元素或类等等)的地方,组装描述工件的模型并返回它。SCA contribution服务在所有注册
了工件处理器的工件上调用ArtifactProcessor.read()。假如你的模型引用了其他的模型,不需要立刻装载那些模型,你只需要保持描述
引用的信息,在resolve阶段,你将会把该信息转换成指向被引用模型的指针。注意:你没有必要在这个时刻完全读取并装载模型,你可以在以后来完成这些
工作。
? 解析阶段:这个阶段让你有机会解析对其他模型的引用。这个时刻,SCA contribution中所有的描述工件的模型都已经读取,并注册了工件解析器,准备被解析。
装载Java SCA
SCA服务装配以SCDL文件的形式被发布到SCA域中。Tuscany运行时工件处理器将SCDL装载成一系列模型对象。这些模型对象是一系列持有元数据信息的Java bean。
有两种装载器:
- StAXElementLoader:从StAX(Streaming API for XML)事件载入XML元素
- ComponentTypeLoader:通过解析文件或内省机制来载入实现的组件类型
装载组件类型
为特定的实现载入组件类型定义:
- 如何做是实现规范
- 也许会装载XML文件(该文件由具体实现来定位)
- 也许内省实现工件(例如 Java注解机制)
- 或其他的任何方式
Loading composite componentType Loader
- 从提供的URL中载入SCDL
- 从composite包解压并载入SCDL
- POJO componetType Loader
- 内省Java 注解
- 利用可插入的注解处理框架来内省Java类
运行时工件的类图