企業擁有多套異構系統(ERP、CRM、大型主機、資料庫)。J2EE 早期僅透過 JDBC、JMS、JAXP 提供有限整合能力。Sun 與 JCP 專家組制定 JCA (Java EE Connector Architecture),作為 J2EE 1.3 核心規格,定義應用伺服器與企業資訊系統 (EIS) 的標準化連接契約。
| 受益方 | 獲益 |
|---|---|
| EIS 廠商 | 開發單一 Resource Adapter,部署至任意相容應用伺服器,無需為每家伺服器客製化 |
| 應用伺服器廠商 | 實作標準系統契約,新增 EIS 連接無需寫客製代碼 |
| 應用開發者 | 學習單一 CCI (Common Client Interface) API,存取所有 EIS,無需學習專有 API |
位於 javax.resource.spi、javax.resource.spi.security,Resource Adapter 必須實作:
| 管理領域 | 關鍵介面 | 核心功能 |
|---|---|---|
| 連接管理 | ManagedConnectionFactory, ManagedConnection, ConnectionManager | 連接池建立、匹配、銷毀、生命週期控制 |
| 交易管理 | XATerminator, LocalTransaction | 支援 JTA 分散式交易 (XA) 與本地交易 |
| 安全管理 | SecurityContext, Subject | 憑證傳播、身份驗證、授權 |
位於 javax.resource.cci,類似 JDBC 的低階 API,四大介面群:
| 群組 | 介面 | 用途 |
|---|---|---|
| 連接 | ConnectionFactory, Connection, ConnectionSpec, LocalTransaction | 取得連接、本地交易控制 |
| 交互 | Interaction, InteractionSpec | 執行 EIS 操作 (查詢、更新、呼叫程式) |
| 資料表示 | RecordFactory, Record, MappedRecord, IndexedRecord, ResultSet | 輸入/輸出資料結構 (對應表單、記錄、結果集) |
| 中繼資料 | ConnectionMetaData, ResourceAdapterMetaData | 描述 EIS 能力、連接屬性 |
Resource Adapter 運行於應用伺服器進程內,透過系統契約接受容器管理;EJB/Servlet/JSP 等客戶元件透過 CCI 與之交互。
以簡單的 .properties 檔案模擬 EIS,示範完整 Resource Adapter 開發流程。
| 類別 | 實作介面 | 關鍵方法 |
|---|---|---|
| ManagedConnectionFactoryImpl | ManagedConnectionFactory | createManagedConnection(), createConnectionFactory(), matchManagedConnections(), JavaBean 屬性設定 |
| ManagedConnectionImpl | ManagedConnection | getConnection(), destroy(), cleanup(), 事件通知 ConnectionEventListener |
| ConnectionImpl | javax.resource.cci.Connection | createInteraction(), getRecordFactory(), close(), 持有 Properties 物件 |
| ConnectionFactoryImpl | ConnectionFactory | getConnection(), getRecordFactory() |
| InteractionImpl | Interaction | execute() 解析 MappedRecord 鍵值,從 Properties 讀取對應值回填 |
| MappedRecordImpl | MappedRecord | 以 HashMap 實作鍵值對記錄 |
| RecordFactoryImpl | RecordFactory | createMappedRecord(), createIndexedRecord() |
public class InteractionImpl implements Interaction {
private Connection con;
public Record execute(InteractionSpec ispec, Record input, Record output)
throws ResourceException {
if (!(input instanceof MappedRecord) || !(output instanceof MappedRecord))
throw new ResourceException("Input/Output must be MappedRecord");
MappedRecord in = (MappedRecord) input;
MappedRecord out = (MappedRecord) output;
Properties props = ((ConnectionImpl) con).getProperties();
for (Object key : in.keySet()) {
out.put(key, props.get(key)); // 從屬性檔讀取值回填
}
return out;
}
// 其他 execute 重載、close、getWarnings 略
}
public class MappedRecordImpl implements MappedRecord {
private Map map = new HashMap<>();
private String recordName, description;
// Map 代理方法
public Object get(Object key) { return map.get(key); }
public Object put(Object key, Object value) { return map.put(key, value); }
public Set keySet() { return map.keySet(); }
// equals, hashCode, clone, Record 介面方法略
}
ra.xml 部署描述符、類別、依賴庫ManagedConnection)ConnectionFactorygetConnection() → createInteraction() → execute() → close()
InitialContext ctx = new InitialContext();
ConnectionFactory cf = (ConnectionFactory) ctx.lookup("java:comp/env/eis/PropertiesFileAdapter");
Connection conn = cf.getConnection();
Interaction interaction = conn.createInteraction();
MappedRecord input = cf.getRecordFactory().createMappedRecord("");
input.put("Message", ""); // 指定要查詢的鍵
MappedRecord output = (MappedRecord) interaction.execute(null, input);
String message = (String) output.get("Message"); // 取得屬性檔中的值
conn.close(); // 歸還連接池
| 限制 | 現狀/改進方向 |
|---|---|
| 缺乏非同步 EIS 存取支援 | JCA 1.5+ 引入 MessageEndpoint、ActivationSpec 支援訊息驅動 |
| 無原生 XML 訊息支援 | 需自行整合 JAXB/SAAJ,或使用 CCI Record 擴展 |
| CCI API 較底層,開發體驗不如 JDBC/JPA | 建議封裝 DAO/Repository 層,或使用 Spring JCA 整合簡化 |
JCA 以雙重標準契約(系統契約 + CCI)實現了「開發一次,部署任意相容容器」的企業系統整合願景。雖然 API 相對底層,但它為資源適配器、連接池、分散式交易、安全憑證流轉建立了統一語言。現代架構中,常搭配 Spring、Mule、Camel 等整合框架使用,屏蔽 CCI 細節,專注於業務整合邏輯。