级别: 中级 李 凌, 软件架构师, IBM
2009 年 8 月 31 日 SCA(Service Component Architecture,服务组件架构)是目前最佳的 SOA 实现方式,IBM Rational Application Developer (RAD) V7.5.2 最新集成了功能强大的图形化的 SCA 开发工具,以帮助用户快速地装配和部署基于开源 SCA 标准(http://osoa.org)的面向服务的应用程序模块。本文详细介绍了使用 RAD 集成开发环境构建 SCA 应用程序的方法。在示例应用程序中,读者可以看到如何使用 RAD 7.5 开发和测试一个 SCA 组件,以及如何装配和测试一个基于 SCA 的组合应用程序。
服务组件架构(SCA)简介
在面向服务的架构(Service Oriented Architecture,SOA)中,业务功能是由一系列装配在一起的服务提供的;通过组合、编排不同的服务,可以快速、灵活地实现不同的业务功能,这正是 SOA 的魅力之一。为了实现这种灵活的 SOA,人们往往需要解决:
-
如何封装现有的软件模块,使得其它应用程序可以方便地使用它;
-
如何装配和组合各种可重用的软件模块,以快速地实现业务功能;
-
如何在软件模块上应用策略,提供访问的 QoS(Quality of Service,服务质量)保障。
这些问题随着 SOA 的发展变得日益复杂。当今的企业 IT 系统中充斥着琳琅满目多种多样的应用程序接口(APIs)、持久层框架、网络协议、以及编程语言;这些异构性使得构建满足企业需要的灵活的 SOA 变得越来越困难。
在这种情况下,SCA(Service Component Architecture,服务组件架构)应运而生,成为了实现 SOA 的一种最佳实践。OSOA(Open Service Oriented Architecture)组织于 2007 年发布了 SCA 及其相关规范的 1.0 版本。它是一种与语言无关的编程模型,提供了统一的 API 接口来隐藏底层的技术实现细节;使得用户可以把不同类型的组件,例如 POJO、EJB、BPEL、人工交互组件等,通过一种标准的接口来封装和调用,从而极大地简化用户的编程,提高应用的灵活性。
一个典型的基于 SCA 构建的系统架构模型如图 1 所示。
图 1. SCA 架构模型
各个子系统包含一个或多个 SCA 组件;每个 SCA 组件包含一个或多个接口(Interface)和引用(Reference),接口提供了外部调用的入口,引用提供了调用外部服务的出口,接口和引用的描述形式可以是 WSDL 或 Java,并且可以与各种不同的访问机制进行绑定,例如 EJB、JMS、SOAP、HTTP 等等;SCA 组件可以由不同的语言和技术实现,例如常见的 Java 和 C++ 语言,这些实现方式对外提供统一的接口和引用,它们的变化不会对外部组件造成影响。此外,通过在接口和引用上贯彻服务策略,可以有效地管理 SCA 组件的 QoS,并且这些策略是与 SCA 组件实现代码相独立的,策略的改变不需要代码的变更。这种组合应用(composite applications)的形式,使得 IT 系统的架构层次更为清晰,IT 资产的重用更为容易,业务功能的实现更为快捷,有效提高了整个 IT 系统的投资回报率。
RAD 对 SCA 的支持
Rational Application Developer for WebSphere Software V7.5 (简称 RAD)是 IBM 推出的新一代集成开发环境。它可以被用于装配、部署和测试组合应用程序,从而实现灵活的面向服务架构。
最新的 RAD V7.5.2 集成了 SCA 开发工具,以便用户快速地在企业级应用程序中装配和集成各种不同的服务模块。通过使用 SCA 开发工具,用户可以:
-
创建 SCA 项目、或为现有项目添加 SCA 支持;
-
使用向导的方式创建 SCA 资产;
-
以图形化的方式实现 SCA 模块的装配,例如将简单的原子服务装配为复杂的组合服务;
-
以图形化的方式为 SCA 模块配置绑定类型(例如 EJB2.x/3.x、SOAP1.1/1.2、SCA)和策略(例如事务、安全性、消息可靠性);
-
装配 SCA 资产,以便发布到 WebSphere Application Server (WAS) 运行和测试。
建立开发环境
要开发 SCA 应用程序,需要安装 RAD V7.5.2 或以上版本;如果已经安装了 RAD V7.5.0 或 V7.5.1 版本,则可以在原先的基础上进行升级。同时,在安装或升级的过程中,确保 Service Component Architecture Development Tools 已被选中;确保选择的测试服务器为 WebSphere Application Server 7.0,并同时安装 WebSphere Application Server 7.0 Feature Packs,如图 2 所示。此外,安装过程中可以选择创建一个兼容 SCA 应用程序的 WAS Profile(概要文件),SCA 组件的测试必须在该 Profile 上进行。
图 2. 选择 SCA 开发工具和测试服务器
开发 SCA 组件
本节介绍了如何使用 RAD 的 SCA 开发工具,创建一个 SCA 项目,并实现和测试一个 SCA 组件。
创建 SCA 项目
首先,在 RAD 中点击 File -> New 打开新建项目向导,选择 SCA Project 创建一个名称为 TestSCA 的 SCA 项目,并选择测试服务器为 WAS V7.0。点击 Finish 完成项目的创建,如图 3 所示。
图 3. 新建一个 SCA 项目
实现 Web 服务绑定的 SCA 组件
切换到 JavaEE 视图,在 TestSCA 项目中添加一个 SCA Composite,并将其命名为 TestComposite,命名空间为 http://test.com,如图 4 所示。SCA Composite 用于组合一个或多个 SCA 模块。
图 4. 新建一个 SCA Composite
然后,在 TestSCA 项目中添加一个 Java 类型的接口,并将其命名为 Echo,所在的包名为 com.test。该接口的定义如清单 1 所示,其中 @Remotable 标注表示这是一个可以被 SCA 组件所使用的接口。
清单 1. Echo 接口定义
package com.test;
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface Echo {
public void echo();
}
|
在 TestComposite 上点击鼠标右键,New -> SCA Component,如图 5 所示,输入 SCA 组件名称为 TestCompA;选择该组件使用的接口类型为 Java 类型,并重用 Echo 接口,这个接口也就是 TestCompA 组件对外的服务接口;选择该组件的实现类型为 Java 类型,并选择创建一个新的实现。点击 Next,指定该 SCA 组件的实现类名称为 com.test.EchoImplA。点击 Finish 完成创建。
图 5. 新建一个 SCA 组件
向导将在 TestSCA 项目的 TestComposite 下添加一个 TestCompA 组件;同时,在 src 目录下添加一个实现了 Echo 接口的 SCA 组件类 EchoImplA.java。然后,在该类中添加一个简单的 echo 方法实现,如清单 2 所示。其中,@Service 标注表示该 SCA 组件所提供的用于外部访问的服务接口是 Echo 接口。限于篇幅,EchoImplA 没有提供业务逻辑的实现,仅仅在 System.out 输出一些组件被调用的描述信息。
清单 2. EchoImplA 对 Echo 接口的实现
package com.test;
import org.osoa.sca.annotations.Service;
@Service (Echo.class)
public class EchoImplA implements Echo {
public void echo() {
/// to-do: add business logic for component A
System.out.println("SCA Component A invoked!");
}
}
|
完整的 TestSCA 项目包结构如图 6 所示。
图 6. 示例 SCA 项目包结构
鼠标双击 TestCompA,可以打开可视化的 SCA 模块装配工具;在模块左侧箭头状标识上点击右键,为该服务接口添加一个 Web Service 绑定,如图 7 所示,表示该 SCA 模块对外提供 Web Service 形式的服务。其他可供选择的绑定类型还有 SCA 和 EJB 方式,不同的绑定类型表示不同的客户端访问方式;同一个 SCA 组件服务接口可以定义多种绑定,以此便捷地满足不同类型客户端的需求。
图 7. 添加 Web 服务绑定
至此,一个简单的 SCA 模块构建完成,该 SCA 模块可以被外部程序以 Web 服务的方式调用。
部署和测试 Web 服务绑定的 SCA 组件
要在 WAS 上部署 SCA 模块,需要为 SCA 项目创建相应的 SCA Contribution。SCA Contribution 用于描述,一个 SCA 项目中哪些 SCA 组件需要被部署到服务器上;不包含在 SCA Contribution 中的 SCA Composite 将不会被部署。
在 TestSCA 项目中点击鼠标右键,新建一个 SCA Contribution,选择可部署的 SCA Composite 为 TestComposite,如图 8 所示,点击 Finish 完成创建。
图 8. 创建 SCA Contribution
启动 WAS V7.0 测试服务器,并确保所使用的服务器概要文件已经集成了对 SCA 项目的支持,即确保使用安装 SCA Feature Pack 时建立的概要文件。
使用服务器的添加删除项目向导,将 TestSCA 项目部署到测试服务器上,如图 9 所示。
图 9. 添加 SCA 项目到测试服务器
确认发布成功后,启动 RAD 的 Web Service Explorer 对 TestCompA 这个 SCA 模块暴露出来的 Web 服务进行测试。如图 10 所示,在 Web Service Explorer 中指定目标服务的 WSDL 地址为:http://localhost:9081/TestCompA/Echo?wsdl (注意端口号视测试服务器配置情况而定),点击 Go 按钮调用 Echo 服务。控制台输出了以下结果,表示 SCA 组件调用成功。
[6/29/09 17:08:05:578 CST] 0000002a SystemOut O SCA Component A invoked!
|
图 10. 测试 Web 服务绑定
实现 SCA 组合应用程序
为了充分展示 SCA 的优势,本节将介绍如何通过装配 SCA 组件来快速构建 SCA 组合应用程序,从而敏捷、灵活地构建一个业务系统。
本节涉及的示例业务系统架构如图 11 所示。
图 11. 示例业务系统 SCA 架构
该假想业务系统包含了子系统 A、B 和 C。子系统 A 是为了满足业务功能而全新开发的,为了将来方便被其它系统复用,它采用 SCA 技术进行构建;主要由 3 个 SCA 组件构成,每个 SCA 组件实现了相对独立的业务功能可以为外部系统所重用;由于同属于一个子系统,因此组件之间使用 SCA 绑定进行装配。SCA 组件可以通过引用(支持多种协议的绑定)的方式重用现有的外部系统,从而减少 IT 投资。本例中,子系统 B 是原有的遗留系统,对外提供了 Web 服务接口,该接口被服务组件 B 以 SOAP 绑定的方式重用;子系统 C 也是一个遗留系统,对外提供了 EJB3 接口,该接口被服务组件 C 以 EJB 绑定的方式重用。整个业务系统对外提供了 Web 服务和 EJB 接口,同时支持这两种客户端的接入,并且这些接口的绑定不需要编写代码即可实现。
整个系统架构体现了 SCA 快速装配、灵活变更、可重用和支持多渠道接入等优点。这些优点使得开发人员可以专注于业务逻辑的编写,把通信、安全、事务等基础能力交给 SCA 容器来管理。
导入资源
为了简化篇幅,将已有的 WebService 和 EJB3 项目导入 RAD 工作区(其项目文件可以从文章末尾处下载),这两个项目分别代表子系统 B 的 Web 服务和子系统 C 的 EJB3 服务。同时,将 WSEchoService.wsdl 和 WSEchoService_schema1.xsd 文件拷贝到 TestSCA 项目的 META-INF 目录下,这两个文件以 WSDL 的形式描述了子系统 B 暴露的 Web 服务接口。打开 WSEchoService.wsdl 文件可以看到服务的位置信息如清单 3 所示,如果 IP 地址或端口号与实际部署情况不符,可自行修改。
清单 3. Web 服务的位置信息
<service name="WSEchoService">
<port name="WSEchoPort" binding="tns:WSEchoPortBinding">
<soap:address location="http://localhost:9081/WebService/WSEchoService"/>
</port>
</service>
|
修改 TestSCA 项目的 Java Build Path 使它依赖于 WebService 和 EJB3 这两个项目,如图 12 所示。
图 12. 设置 TestSCA 项目依赖关系
添加 TestCompB 服务组件
为了展示 SCA 组件的装配过程,需要在现有的 TestSCA 项目中添加一个 SCA 组件。方法是,在 TestComposite 上新建一个名为 TestCompB 的 SCA 组件;选择接口类型为 Java,并复用 com.test.Echo 接口;同时选择创建一个新的 Java 类型的实现类,实现类的名称命名为 EchoImplB。如图 13。
图 13. 添加 TestCompB 服务组件
创建完成后,可以在项目文件夹 SCA Content 中看到新增加的 TestCompB 这个 SCA 组件;同时,源代码 src 目录下也可以看到新增加的 EchoImplB.java 这个 SCA 组件实现类。
打开 EchoImplB.java 文件,在 EchoImplB 类中添加如清单 4 所示的代码逻辑。其中,@Reference 标注表示该 SCA 组件引用了一个类型为 WSEcho 的外部接口(位于子系统 B 中),并通过 reference_ws.echo() 调用该接口中的方法。限于篇幅,EchoImplB 没有提供业务逻辑的实现,仅仅在 System.out 输出一些组件被调用的描述信息。
清单 4. EchoImplB 对 Echo 接口的实现
package com.test;
import org.osoa.sca.annotations.Service;
@Service (Echo.class)
public class EchoImplB implements Echo {
@Reference
public com.exist.WSEcho reference_ws;
public void echo() {
/// to-do: add business logic for component B
System.out.println("SCA Component B invoked!");
// invoke external Web service in subsystem B
reference_ws.echo();
}
}
|
接着,打开 SCA Composite 装配视图,为 TestCompB 组件添加一个引用,同时在引用的属性栏中重命名引用名称为 reference_ws,并为该引用设置一个 Web 服务类型的绑定,如图 14 所示。
图 14. 添加 Web 服务引用
为了使这个 Web 服务引用可以顺利调用到子系统 B 中的 Web 服务,打开 Web 服务引用的属性菜单,按照 WSEchoService.wsdl 文件的定义,修改 Web 服务绑定的 WSDL Element 属性;设置 WSDL 元素类型(Element Type)为 Port,输入引用的元素名称(Element Name)为 WSEchoService/WSEchoPort,WSDL 命名空间为 http://exist.com/,如图 15 所示。
图 15. 设置 Web 服务绑定属性
Web 服务引用设置完成后,切换到 SCA 组件装配图,为 TestCompB 组件的接口设置一个 SCA 绑定,表示它将以 SCA 服务的方式对外提供服务,如图 16 所示。
图 16. 添加 SCA 绑定
添加 TestCompC 服务组件
为了完成这个组合应用程序,还需要在 TestSCA 项目中添加 TestCompC 服务组件。方法是,参考上一小节创建 SCA 组件的过程,在 TestComposite 上新建一个名为 TestCompC 的 SCA 组件;选择接口类型为 Java,并复用 com.test.Echo 接口;同时选择创建一个新的 Java 类型的实现类,实现类的名称命名为 EchoImplC。创建完成后,打开 EchoImplC.java 文件,在 EchoImplC 类中添加如清单 5 所示的代码逻辑。其中,@Reference 标注表示该 SCA 组件引用了一个类型为 EjbEchoRemote 的外部接口(位于子系统 C 中),并通过 reference_ejb.echo() 调用该接口中的方法。限于篇幅,EchoImplC 没有提供业务逻辑的实现,仅仅在 System.out 输出一些组件被调用的描述信息。
清单 5. EchoImplC 对 Echo 接口的实现
package com.test;
import org.osoa.sca.annotations.Service;
@Service (Echo.class)
public class EchoImplC implements Echo {
@Reference
public com.exist.EjbEchoRemote reference_ejb;
public void echo() {
/// to-do: add business logic for component C
System.out.println("SCA Component C invoked!");
reference_ejb.echo();
}
}
|
接着,打开 SCA Composite 装配视图,为 TestCompC 组件添加一个引用,重命名引用的名称为 reference_ejb 并设置引用绑定类型为 EJB 绑定。为了使该引用能够顺利查找到目标 EJB 服务,在引用的属性菜单中设置 EJB 绑定信息如图 17 所示,设置 EJB 会话 Bean 属性为无状态(stateless),EJB 版本为 3.0,目标 EJB 的主机地址为 localhost,名称服务查找端口为 2810(视测试 WAS 服务器配置而定),目标 EJB 的 JNDI 搜索串为 NameServiceServerRoot#ejb/EJB3EAR/EBJ3.jar/EjbEcho,目标 EJB 的业务接口为 com.exist.EjbEchoRemote。
图 17. 设置 EJB 绑定属性
重构 TestCompA 服务组件
为了使 TestCompA 组件能够顺利调用 TestCompB 组件,需要给 TestCompA 组件添加一个引用,如图 18 所示。
图 18. 添加 SCA 引用
在 TestCompA 组件的 Properties 窗口中重命名引用的名称为 reference_b,同时为该引用添加一个 SCA 绑定,表示该引用访问外部服务时将使用 SCA 方式调用,如图 19 所示。
图 19. 设置 SCA 引用及绑定的属性
同样,也需要在 TestCompA 组件上创建一个针对 TestCompC 组件的引用,修改引用名称为 reference_c,并设置引用的绑定类型为 SCA 绑定。
完成这两个引用的添加后,在 SCA 组件装配图中将 TestCompA 的 reference_ b 引用与 TestCompB 的服务接口相连接;将 reference_c 与 TestCompC 的服务接口相连接。
打开 TestCompA 组件的实现类 EchoImplA.java,更新实现代码如清单 6 所示。其中引用 reference_b 和 reference_c 分别用于访问 EchoImplB 和 EchoImplC 服务组件。
清单 6. 在 EchoImplA 中添加引用
package com.test;
import org.osoa.sca.annotations.Service;
@Service (Echo.class)
public class EchoImplA implements Echo {
@Reference
public Echo reference_b;
@Reference
public Echo reference_c;
public void echo() {
/// to-do: add business logic for component A
System.out.println("SCA Component A invoked!");
reference_b.echo();
reference_c.echo();
}
}
|
最后,为 TestCompA 组件的服务接口再添加一个 EJB 绑定,并命名为 ejb_svc ,表示它可以通过 EJB(有状态会话 Bean 或者无状态会话 Bean)的方式对外提供服务。这样 TestCompA 组件将可以同时支持 Web 服务方式和 EJB 方式的访问。最终 TestSCA 项目的 SCA 组件装配图如图 20 所示。TestSCA 项目的完整代码可以从文章末尾处下载。
图 20. 完整的 SCA 模块装配图
部署并测试组合应用程序
将 TestSCA、EJB3EAR 和 WebServiceEAR 3 个项目部署到测试服务器。
为了模拟 Web 服务客户端用户的访问,启动 Web Service Explorer 测试客户端,仍旧对 TestCompA 组件暴露出来的 Web 服务发起调用,可以观察到调用流程依次经过组件 A、组件 B、外部 Web 服务、组件 C、最后到达外部 EJB 服务,控制台输出的测试结果如下。
[7/2/09 16:26:43:078 CST] 000000b7 SystemOut O SCA Component A invoked!
[7/2/09 16:26:43:078 CST] 000000b7 SystemOut O SCA Component B invoked!
[7/2/09 16:26:43:125 CST] 00000063 SystemOut O Web Service component invoked!
[7/2/09 16:26:43:140 CST] 000000b7 SystemOut O SCA Component C invoked!
[7/2/09 16:26:43:171 CST] 000000b7 SystemOut O EJB3 component invoked!
|
为了模拟 EJB 客户端用户的访问,启动 RAD 中的 Universal Test Client,找到 TestCompA 组件暴露的 EJB 接口 ejb/sca/ejbbinding/TestCompA/Echo,并发起调用,可以观察到测试结果和通过 Web 服务方式访问相同。
总结
本文首先介绍了服务组件架构 SCA 这种 SOA 最佳实践的特点和优势,然后详细描述了使用 IBM RAD 开发 SCA 组件的方法,并以 SCA 组合应用程序的形式构建了一个假想的业务系统,该构建过程充分体现了 SCA 架构模式的灵活、敏捷、易于重用等特点,同时也体现了 IBM RAD 集成开发工具对 SCA 应用程序开发的良好支持。
参考资料 学习
获得产品和技术
讨论
关于作者  | 
|  | 李凌,IBM 中国软件开发中心软件架构师,主要负责 WebSphere 相关产品的咨询、培训和实施工作;从 2007 年以来主要从事 SOA(Governance)解决方案咨询与实施工作;在 Web 服务、信息安全和 IP Multimedia Subsystem 领域有丰富的实践经验。 |
对本文的评价
|