本文阐述了服务数据对象 (SDO) 体系结构的关键概念,以及它所提供的强大功能和灵活性。SDO 体系结构在 Java(TM) 2 Platform Enterprise Edition (J2EE) 社区正获得越来越广泛的普及,它也用于构建面向服务的体系结构 (SOA) 的环境。在 IT 解决方案日趋复杂和越来越多地采用分布式体系结构的今天,它可以满足异构数据集成的需要。
服务数据对象 (SDO) 通过 Java Specification Request (JSR) 235得到了 Java™ 社区的认可,它也是 CommonJ的一部分,CommonJ 是 IBM 和 BEA 共同制定的规范。如何访问不同数据源类型的数据在 IT 业界变得越来越重要,SDO 是一种应用程序编程接口 (API),可以简化和统一对异构数据的访问。目前单一数据类型的应用程序已经不再常见,信息通常都存储在不同类型的数据源中(比如数据库、Web 服务、轻量级目录访问协议 (LDAP)、遗留应用程序等等)。这种复杂性要求开发人员熟悉许多 API(比如 Java 数据库连接 (JDBC)、基于 XML 的远程过程调用的 JAVA API (JAX-RPC)、或者 J2EE 连接器体系结构 (JCA) 等等)。SDO 简化和补充了 Java 2 Platform Enterprise Edition (J2EE) 的开发模式,提供了一种独特的访问异构数据源的 API,同时也可用于数据处理的其他方面,本文将对此进行详细说明。
SDO 的目标有很多,从某种程度上讲 SDO 看起来好像是 J2EE 的一把多功能“瑞士军刀”,因为它包含的特性可实现多种不同种类的功能,基本来讲,SDO 及其相关的技术设计有以下五大主要专题:
简化数据访问:第一个目标是提供对多种企业信息系统 (EIS) 的统一的数据访问,包括数据库、遗留应用程序(使用 JCA)、XML 或者是 Web 服务数据源。通过使用 SDO 的一种独特而简单的模型,应用程序摆脱了使用多种 API 和框架进行数据访问的复杂工作。
数据提取:使用 SDO 后,数据的表示是独立于其数据源的,它采用了一种叫做 Domain Store 的 J2EE 模式,这种级别的数据提取有很多优点,例如使数据操作变得更容易,实现了不同层之间的松耦合。
数据操作:一旦检索到信息后,SDO 会提供一种统一的编程语言进行数据操作,简单的说,就是通过使用 API 及其接口,SDO 客户机可以读取数据和修改数据。SDO 为此提供了连接和断开连接的两种模型,下文中将对此做详尽的介绍。
数据传输:SDO 有一部分概念是关于传输对象 (Transfer Object) 和传输对象组装程序 (Transfer Object Assembler) 模式的。数据封装到 SDO 对象中后,它就可以在 J2EE 层间高效地传输。
设计模式的采用:SDO 的一个关键目标是鼓励大家采用公用的 J2EE 模式,这也是 SDO 体系结构以一些广为人知的模式为基础的原因,例如传输对象 (Transfer Object)、数据访问对象 (Data Access Object)、传输对象组装程序和 Domain Store等。如果使用了 SDO,应用程序就可以从这些经过了验证的设计策略中受益,从而可以推动分层技术和松耦合的发展。
图 1 显示了 SDO 在一个 J2EE 分层体系结构中所处的位置:
图 1. J2EE 分层体系结构中的 SDO
SDO 体系结构提供了一组核心组件,这些组件可以由支持 SDO 的实现和框架进行扩充。
SDO 规范定义了数据持有者(数据对象 (Data Object) 和数据图 (Data Graph)),还引用了一种叫做数据中介服务(Data Mediator Service,DMS)的组件。DMS 负责访问数据源和处理数据图,如图 2 所示:
图 2. DMS 的角色
图 3 显示了 SDO 体系结构和它的关键组件,如下所示:
图 3. SDO 体系结构
数据对象是保存数据的组件,简单地说,它是由属性的键/值对组成的,每个值都可以是原始的数据类型,或者是另一个数据对象。数据对象是可序列化的。
设想一下您需要显示餐馆甜点的有关信息,其对应的数据对象实例可以包含下列值:
清单 1. 数据对象值示例
<ID, 123>
<Description, "Chocolate Cake">
<Price, 7>
对于熟悉 JDBC 概念和 java.sql.ResultSet 接口的读者来说,SDO 的动态 API 模式是很容易理解的。就像 JDBC 一样,您可以通过名称或索引来访问它的属性值。
如果在程序运行之前,还无法获知准确的数据结构的话,使用动态 API 是特别适合的。
SDO API 提供一些简单易用的方法来获取数据对象中的值:
清单 2. 获取数据对象中的值
// returns the first element of the graph
DataObject dessert = (DataObject) graph.get(0);
// get the dessert name and its price
String dessertName = dessert.getString("Description");
int dessertPrice = dessert.getInt("Price");
如果在开发阶段数据结构就可以确定的话,SDO 体系结构还提供了静态 API 功能。例如,如果数据源是一个带有明确定义模式(xsd 文件)的 XML 文件的话,则 SDO 将支持 Java 代码生成和 Java 绑定。虽然这已经超出了 SDO 规范的范围,但是绑定技术可能会集成一些对 SDO 的支持,例如 XML 数据绑定的 Java 体系结构 (JAXB)。
数据对象图是一个描述数据的分层结构,它包括一个数据对象树和另一个称作更改摘要 (Change Summary) 的结构(请参阅图 4)。更改摘要记录了数据图中所有数据对象的历史更改信息。此外,由于数据图是由数据对象组成的,因此它是可序列化的。
图 4. 数据对象图
元数据是一个描述对象内容的元模型,它可以让数据图实例完成自省 (introspection)。
如图 5 所示,每个对象都与一些基本的元数据信息相关联,对象以一个类型加一个已排序的属性列表的形式表示。
图 5. 对象元数据
SDO 体系结构还包括了一些规范中没有定义的附加组件。
前面一段描述了信息的逻辑元数据(例如当信息加载到 SDO 对象后的元数据),而物理元数据(例如原始数据源格式的元数据)不在 SDO 规范讨论的范围内。典型情况下,物理元数据并不会影响 SDO 客户机,但是它会影响到 DMS,DMS 是负责访问数据源的组件。
DMS 是一种组件,它负责提供某些方法来组装数据图,也负责将数据更改保存回数据源。典型情况下,将会有多种不同的 DMS 类型,每种类型对应着一种特定的数据源和技术(XML、JMS、JCA、JDBC 等等)。DMS 总是以同一种格式(数据图)返回信息,它隐藏了实际的数据存储信息,在 SDO 应用程序和 EIS 之间提供了一层数据提取的功能。
DMS 不在 SDO 规范的范围内,但是它在实现中可能需要将多个数据源和数据类型的数据集成在一起,这样,唯一的 SDO 数据图就会包含了异构数据源的信息。请参见图 6:
图 6. DMS
SDO 模型有一个有趣的特性,就是它允许使用断开连接的编程模型,事实上当 SDO 客户机提出数据图请求并收到此数据图后,它就断开了和 DMS 的连接,这样避免了 DMS 对数据源的持续加锁,客户机就可以不受时间限制地处理数据对象,对数据源的更改保存以一种乐观的并行方式进行。这种断开连接的模型特别适合 n 层的以 Web 为基础的体系结构,因为它考虑到了分层技术,同时也易于使用,而且还可以进行高级并行访问。
请求 SDO 图
图 7 是一个简单请求的序列关系图。基本上,当一个 SDO 客户机需要检索数据时,它使用 DMS 来请求数据图,DMS 负责管理对数据源的访问,并根据接收到的信息来创建一个图,通常这个图是一个分层的树结构,其中包含了几个数据对象。此客户机使用断开连接的编程模型来处理数据图。如果数据被修改,而且客户机希望能保存这些更改,它会将更改后的数据图发送给 DMS,然后由 DMS 去修改数据源。
图 7. SDO 图
数据图中的所有对象扩展了可序列化的 Java 接口,这样,树的序列化是很简单的,但是必须注意以下模式,如图 8 所示。
图 8. 序列化数据图
目前来讲,规范并没有明确说明该如何描述数据图。其中一个称为“model”的元素支持 Essential Meta Object Facility (EMOF),而另一个称为“xsd”的元素可用来存放 XML 模式。SDO 对这两者都支持,这两种元素的作用也都一样:用于描述元数据。
序列化完成后,数据图由三部分组成:模式、序列化的数据对象和更改摘要,如图 9 所示。数据对象部分包括了树型结构和对象的值,而更改摘要则列出了序列化完成前数据图的所有更改,原始树结构中未更改的数值则被省略了。数据图框架模式仅在需要反序列化的情况下才出现,如前所述,它可以是 XSD 或者是 EMOF 模型。
图 9. 序列化的数据图的三个组成部分
SDO 有一个很重要的特点就是使数据操作变得更容易了,因此一旦构造好一个数据图,很重要的一点就是需要使用 SDO API 来遍历树结构,并访问其中的元素。规范的作者选择了使用 XPath 语言来完成这一工作。XPath 应用在 SDO 中时它仅有一个特殊的地方:在访问数据时,它使用 0 作为基本索引,而 XPath 规范中第一个元素只能通过索引值 1 识别,这个特殊的规定是为了使 SDO API 更接近 Java API,因为编程人员习惯了在引用数组的第一个元素时,使用 array[0] 这样的语法来表示。
我们来看一个简单的例子:餐馆的菜单,体会一下如何处理数据图中的数据对象。它可以用以下的统一建模语言 (UML) 关系图来描述,如图 10 所示。
图 10. 数据图中的数据对象(用 UML 关系图描述)
一个特定的 SDO 图实例如下所示:
图 11. SDO 图
首先需要获取图的根元素,这是一切工作的起点:
DataObject root = dataGraph.getRootObject();
要访问 Menu 对象,只需使用:
DataObject menu = root.getDataObject("Menu");
现在查看的是哪一类菜单呢?下面的表达式将会告诉您:
String menuType = menu.getString("Name"); //
顺便提一下,这是正餐。
现在假定您想点主菜。您需要了解今天的菜单上都有些什么菜:
DataObject mainDish = menu.getDataObject("coursetype[Type='Main']");
如果您决定点丁字牛排 (T-Bone),您可以根据它的索引直接从数据图中访问它:
DataObject tBone = (DataObject) mainDish.get(0);
要查看您是否带了足够的钱来付账,可以获取价格:
int tBonePrice= tBone.getInt("Price");
您还饿吗?来点甜点如何?首先您可以调出树结构中甜点的清单,以便做出决定:
DataObject dessert = menu.getDataObject("coursetype[Type='Dessert']");
List dessertList = dessert.getList();
接下来您可以访问刚才所获得的顺序集合中的元素。或者可能您已经决定了选择美味的巧克力蛋糕。您可以使用以下表达式来直接访问它:
DataObject cake = menu.getDataObject(coursetype.2/dishes.2);
XPath 的使用使访问数据对象图的元素变得简单而直观。SDO API 中还有很多附加的特性可用于创建或删除对象,或者是改变它们的值。
到目前为止,SDO 看起来不只是一个 API,它还是一个设计和编程模型,所以 SDO 可以(或者将来有可能)在多个企业应用程序概念中使用。我们现在来看看其中的一些例子。
使用 SDO 的目的并不是替换现有的持久性机制,而是利用它们提供一个统一的编程接口。典型地,编程人员将只专注于唯一的编程模型 (SDO),而不用学习多种 API 和框架。取而代之的是在幕后由支持 SDO 的工具和 DMS 来处理所有特定而繁琐的数据源语义。这样,即使在不知道数据源的情况下,SDO 客户机都可以通过 DMS 与 JDBC、Java 数据对象 (JDO)、Hibernate、Entity Enterprise JavaBean (EJB)、 Web 服务及任何其他数据源进行交互。
SDO 对象是独立于底层数据源的,它们将信息封装在简单原始的 Java 对象(POJO)中,与一些特定技术(如 EJB 或 Servlet)没有什么关系。
因此,在 J2EE 体系结构中,SDO 对象是跨级使用的最佳候选对象。它们可以首先由集成层 (integration layer) 创建为值传递的 Java 对象,然后发送给业务层。此外 SDO 对象可以在表示层和业务层间传递信息。(请参阅参考资料获取更多的关于传输对象 (Transfer Object) 模式的信息。)
最近人们越来越多地在致力于使用户界面组件 (UI) 和业务服务间实现自动绑定,而不需要考虑所使用的具体技术。例如,怎样使 JavaServer Faces (JSF) 组件以标准的方式与 EJB 或 Web 服务实现交互?如何让 Struts 组件使用同一标准?SDO 提供了相应的对象和 API 来轻松地实现 JSR227 工作组确定的绑定需求(请参阅参考资料)。
SDO 采用的模型是规范化的和可自动描述的,因此它可用来使工具和框架以标准方式自动访问数据和生成 Java 对象。SDO 还具有自省功能和拥有动态数据 API,这样就可以轻松地与现有的和即将出现的工具相集成。如果能被广泛接受的话,作为一个公用 API,SDO 将统一现有的数以千计的框架结构。
SOA 旨在推广一种可互换的、适应性强的和灵活的行业标准框架。这都要求提供随需应变的业务,但是在 IT 基础设施中,SOA 还仅仅只是一个概念或者说是一个蓝图。业界已经采用了 Web 服务标准来实现 SOA 的应用程序。Web 服务展示了一种独立的自描述功能,这样其他应用程序可以通过开放的标准来寻找和访问它。Java 社区可以依靠一组 API 和相关技术来发布、发现和使用服务,这意味着您可以使用定义明确的协议(如简单对象访问协议 (SOAP))来和外部应用程序交互。
但是到目前为止,在应用程序内传递信息还没有标准的方式,当然,这也可以通过自己开发 Java 对象或利用 XML 绑定如 JAXB、Castor、XMLBeans 或很多今天的其他技术来实现,但是您真的希望被这些各式各样的技术和框架绑住手脚吗?
在这种情况下,SDO 可以提供帮助,它提供了一种独特的模型来存放结构化的和相互关联的复合对象,您的应用程序可以使用这些对象来保存信息。而且,对种类繁多的数据源和业务 SDO 提供了一个统一的数据访问。它还可以在业务处理和信息源间实现解耦合。从某种意义上讲, SDO 框架可以简化和统一 SOA 中的数据应用程序开发,它提供了一种标准化的和与厂商无关的方法来处理异构问题。
SDO 规范 1.0 版于 2003 年末提交给 Java Community Process,并获得了批准,但它仍在不断的发展中。和其他所有提交的规范一样,很难预料它最终是否会被广泛地采用,不过,这个规范得到了主要的 Java 行业风险投资的支持,它也确实着重于解决通用企业应用程序的一个重要问题:异构数据访问。SDO 为业务数据提供了一种中立的表示方法,建立了一种与数据源无关的模型,降低了耦合度。基于以上原因,它可能会成为将来 SOA 应用程序的一个重要组件。
本文转自developerWorks 中国 作者:Jean-Louis Marechaux |
2008/10/22 9:26
|