开始
本教程是关于 Java™ 2 企业版(J2EE)连接器架构(JCA)的概览。本教程开头从一个高层次的视角切入 JCA,介绍了它在 J2EE 架构中的位置、它如何集成企业级系统,以及该架构的基础元素。在本教程接下来的章节中,将用循序渐进式的说明和样例带您深入探讨每一个元素更多的细节。教程结尾是一个样例应用程序,用来帮助您整体了解一个兼容和支持 JCA 的系统的所有部分是如何协作的。
为更好地学习本教程,您应该熟悉 Java 编程和面向对象编程概念。您也应该对 J2EE 和 J2EE 应用程序有深入的理解。
本教程提供样例代码(helloworldra.zip),并将逐步解释。为执行并测试样例代码,需要一个支持 J2EE 连接器架构的 J2EE 应用服务器环境。源代码以标准 J2EE 包的形式提供;参见您的应用服务器环境以获取部署详情。
简介
开发基于 Web 的应用程序时,您很可能会需要将这些应用程序与至少在一个企业信息系统(EIS)中可用的资源和数据集成起来,如企业资源规划(ERP)系统、供应链管理(SCM)系统或一个交易处理监控器(TPM)。这种集成是电子商务策略的本质:我们利用并转换现有的基础设施,将其与 Web 和其他开放技术联合起来以支持新的业务过程,如企业间(B2B)交易。
在 J2EE 连接器架构到来之前,将 J2EE 应用程序和 EIS 集成起来很复杂,并且问题重重,因为尚不存在关于此类集成的标准。每个 EIS 供应商都为该问题提供了自己的解决方案。单个的 EIS 供应商通常不支持所有 J2EE 应用服务器。这些情况致使编写与企业信息系统集成到一起的真正可移植的应用程序十分困难;因为要集成每个应用服务器和 EIS 就需要进行定制。
下图展示了 J2EE 应用程序和 EIS 集成的复杂度。
J2EE 连接器架构(JCA)解决了将 J2EE 应用服务器连接到 EIS 的这个问题。通过遵循 JCA 标准,EIS 供应商确保其 EIS 能与任何基于 Java 的应用服务器轻易地集成起来。这样,应用服务器供应商也只需要确保其产品允许 JCA 连接性,而不用针对市场上的每个 EIS 定制其产品。每个允许 JCA 的应用服务器都能与任何兼容 JCA 的 EIS 相集成。
下图显示了 JCA 是如何简化将多个应用服务器连接到单个 EIS 上或将单个应用服务器连接到多个 EIS 上的。
JCA 由三个主要元素组成:
- 系统契约
- 客户机 API
- 资源适配器模块
这些元素中的每一个元素都在 JCA 中发挥着特定的作用。我们将从一个高层次的视角分别介绍每个元素,然后再在后续章节中继续进行更为复杂的探讨。
系统契约 定义应用服务器和 EIS 间的连接。系统契约中的 EIS 端是由一个资源适配器 实现的,它是一个特定于 EIS 的系统级软件驱动程序。应用服务器和资源适配器依赖系统契约进行协作,以提供对 EIS 的安全的、健壮的、可伸缩的访问。
三种系统契约的定义如下所示:
- 连接管理 契约实现到 EIS 的物理连接并为应用服务器提供一种机制来集中控制这些连接。
- 事务管理 契约支持在事务上下文中对 EIS 进行访问。事务可以由应用服务器进行管理,并提供与除 EIS 外的其他资源进行协作的事务;它们也可以是 EIS 资源管理器的内部事务,在这种情况下不需要事务管理器。
- 安全性 契约支持对 EIS 的安全访问。
系统契约在每一端(应用服务器和资源适配器)如何 实现并不由 JCA 指定;它们可以根据供应商的意愿实现。
JCA 的第二个元素是客户机 API。该 API 可以特定于资源适配器,也可以是由 JCA 定义的标准通用客户机接口(CCI)。CCI 是供应商用来提供集成工具和框架的,这就使得开发人员能够更加容易地访问企业系统。推荐采取(不是强制)资源适配器利用 CCI 的方式。
资源适配器模块包含向应用程序提供 EIS 连接的所有必要元素。资源适配器模块包含下列组件:
- 实现资源适配器的 Java 类和接口
- 资源适配器所需的任何实用 Java 类
- 任何特定于 EIS 且依赖于平台的本地库
- 部署描述符
应用服务器利用和资源适配器一起提供的部署描述符 来将其配置到特定的操作环境中。
资源适配器模块的所有文件都被打包到一个资源适配器档案(RAR)文件中(使用 Java 档案 JAR 文件格式)。所有的 Java 类和接口都被打包到一个 JAR 文件中,该文件随后由 RAR 文件所包含。本地文件也打包到该 RAR 文件中。部署描述符名为 ra.xml,位于该 RAR 文件的 META-INF 文件夹中。
JCA 的基础设施
对 JCA 有了基本的了解之后,就可以开始更多地关注在该架构下工作的元素了。在本节中,您将了解到类、接口和库,它们协作来创建和管理连接、完成复杂事务以及维护兼容和支持 JCA 的系统的安全性。
应用程序组件通过 ConnectionFactory
和 Connection
接口来访问资源适配器,这些接口由资源适配器实现程序提供。这些接口可以是 CCI 接口(javax.resource.cci.ConnectionFactory
和javax.resource.cci.Connection
),也可以特定于资源适配器。实现这些接口的类也同资源适配器一起提供。
通过 Java Naming and Directory Interface(JNDI)来获取连接工厂,这样,应用程序就不需要了解底层的实现类。一旦检索到连接工厂,即通过 getConnection()
方法从连接工厂获取一个连接。至少有一个getConnection()
方法必须由连接工厂提供,当然,连接工厂也可以提供更多方法。注意:这一点很重要,即Connection
是一个应用程序级句柄,该句柄指向到 EIS 的底层的物理连接,由 ManagedConnection
表示,我们将在稍后讨论。
应用组件一旦结束连接,它会对连接调用 close()
方法。资源适配器需要为该连接提供一个方法来关闭它。这个方法必须代理 ManagedConnection
(创建该连接句柄的类)的 close
方法。关闭连接句柄不应该关闭到 EIS 的物理连接。
连接工厂中的 getConnection()
方法并不真的创建一个连接;它在其相关联的 ConnectionManager
上调用allocateConnection()
方法。ConnectionManager
接口由应用服务器实现。当连接工厂实例化后,ConnectionManager
接口以一个特定于实现的行为与连接工厂相关联。对 ConnectionManager
的调用就使应用服务器与资源适配器的功能得以紧密结合,从而提供池、事务和安全服务。ConnectionRequestInfo
对象可以被传递到 allocateConnection()
,从而传递特定于连接请求的信息。
ConnectionManager
依次调用一个 ManagedConnection
来获取连接句柄。该连接句柄通过ConnectionManager
传回连接工厂和应用组件。
为支持连接池,资源适配器提供一个实现 ManagedConnectionFactory
接口的类。ManagedConnectionFactory
类可充当连接工厂实例和 ManagedConnection
实例的工厂。
当应用服务器需要创建连接工厂时,它会调用 createConnectionFactory()
方法,传递一个ConnectionManager
实例;这是在应用组件对连接工厂调用 getConnection()
时调用的实例,正如之前所讨论的那样。
应用服务器使用两个 ManagedConnectionFactory
方法中的一个来创建或请求受管的连接。服务器需要ManagedConnection
的一个新 实例时,它会调用 createManagedConnection()
方法。服务器想要重用现有的 ManagedConnection
时,它会调用 matchManagedConnections()
方法。为找到正确的匹配,服务器传入一个可能达到所请求的连接的标准 ManagedConnection
集合,也传入所需连接类型的信息。matchManagedConnection()
方法在内部将此信息和备选集合进行比较,从而决定是否匹配。如果匹配,返回相匹配的 ManagedConnection
;否则,返回 null
。
应用服务器使用大量额外的 ManagedConnection
方法来方便连接池操作,如下所示:
cleanup()
方法清理任何由给定的ManagedConnection
所维护的特定于客户机的状态,并验证与该连接相关联的连接句柄。- 当服务器不再需要连接池中的
ManagedConnection
时,调用destroy()
方法;调用destroy()
方法开始关闭到 EIS 的物理连接。 addConnectionEventListener()
方法允许应用服务器向ManagedConnection
注册一个ConnectionEventListener
,这样,在结束、错误和事务发生时,应用服务器就能得到通知。
此图显示了连接池过程:
JCA 中含两类事务管理。第一类涉及一个事务管理器来协调贯穿单个事务的多个资源管理器。第二类涉及一个事务,该事务只有单个的资源管理器,称作本地事务。资源适配器也能通过部署描述符指示,但它并不支持事务。
多个资源管理器参与由 Java 事务 API (Java Transaction API, JTA) XAResource
接口支持的相同的事务。此接口允许事务管理器管理支持该接口的多项资源间的事务。ManagedConnection
接口包含一个getXAResource()
方法,该方法返回一个 XAResource
对象。应用服务器的事务管理器使用此对象来管理事务。要了解更多有关 XAResource
的信息,请参见 JTA 规范。
为支持本地事务,ManagedConnection
接口提供一个 getLocalTransaction()
方法,该方法返回一个LocalTransaction
对象。LocalTransaction
接口有针对底层 EIS 的方法,用以开始、提交和回滚事务。除此之外,当应用组件开始、提交或回滚一项事务时,ManagedConnection
必须通知其注册的ConnectionEventListener
。为此目的,ConnectionEventListener
接口提供localTransactionStarted()
、 localTransactionCommitted()
和 localTransactionRolledback()
方法。下图说明了这个目的:
尽管 getXAResource()
和 getLocalTransaction()
方法,以及 ConnectionEventListener
通知是资源适配器用以支持事务所需的全部,但事务管理是复杂的,需要资源适配器和应用服务器间相当的协作。为有效地提供对 EIS 的事务支持,需要详细理解 JTA、Java 事务服务(Java Transaction Service,JTS)和 JCA 的事务管理契约。 参见 参考资料,深入阅读关于这些主题的文章。
JCA 的安全性契约使用 Java 认证及授权服务(Java Authentication and Authorization Service,JAAS)的Subject
类来提供安全性信息。当创建了新的 ManagedConnection
,createManagedConnection()
方法被传入一个 Subject
实例。该连接在试图登录到 EIS 时使用该 Subject
。Subject
包含关于 Principal
或Subject
名称的信息,也包含由 principal 持有的安全证书的信息。
JCA 定义两类证书。GenericCredential
是一个 Java 包装,代表一项具体的安全性机制,如 Kerberos 证书。PasswordCredential
持有用户名和密码信息。应用服务器必须提供这两个接口的实现。
资源适配器的部署描述符列示了支持的安全类型、使用的认证机制、证书支持的接口,以及是否支持重新认证。ManagedConnection
的 getConnection()
方法将 Subject
作为参数来支持重新认证。下图显示了安全性管理过程。
由于资源适配器上只有两个方法涉及到安全性,安全性管理似乎有些简单。然而,正如事务管理一样,复杂之处在于应用服务器和资源适配器之间的协作。需要对 JAAS 和 JCA 安全性契约有全面的理解,从而确保有效的安全性。参见 参考资料 获取更多有关 JAAS 的信息。
尽管在 JCA 的三个系统契约中并没有明确地提及,但 ManagedConnectionMetaData
接口是 JCA 的一个重要组件。它提供方法用以检索关于 ManagedConnection
和连接的 EIS 的信息。信息包含:
- EIS 的产品名
- EIS 的产品版本
- EIS 能够支持的连接的最大数目
- 连接的用户名