SCA (Service Component Architecture) Java 實現模型為在 Java 中開發 SCA 組件提供了標準化框架。組件實現既可以作為服務提供者,也可以作為其他服務的客戶端。本文將詳細說明 SCA Java 組件實現與非 SCA Java 組件如何獲取服務訪問權限並調用服務方法。文中所有元數據均採用 J2SE 5.0 的 Annotation 功能定義,但 SCA 服務客戶端與組件實現也兼容 J2SE 1.4 環境。
該模型描述了本地或遠程服務的實現方式,以及特定於實現的配置屬性。
服務通過接口表示,接口定義方式包括:
Java 類組件實現需實現服務接口定義的所有操作,並使用 @Service Annotation 指定該組件作為服務實現的接口。類本身不一定需要 @Service Annotation,但若用於服務實現則建議添加。@Service 擁有兩個屬性:
@Service 無意義。// 清單 1. Java 服務接口
package services.payrolldata;
public interface PayrollDataService {
float getBasic(String employeeID);
float getVariablePay(String employeeID);
float getHRA(String employeeID);
float getProfessionalTax(String employeeID);
float getNetPay(String employeeID);
}
// 清單 2. Java 服務組件實現
package services.payrolldata;
import org.osoa.sca.annotations.*;
@Service(PayrollDataService.class)
public class PayrollDataServiceImpl implements PayrollDataService {
public float getBasic(String employeeID) { ... }
public float getVariablePay(String employeeID) { ... }
public float getHRA(String employeeID) { ... }
float getProfessionalTax(String employeeID) { ... }
public float getNetPay(String employeeID) { ... }
}
若服務接口由實現類本身定義,則 @Service 可寫為 @Service(PayrollDataServiceImpl.class)。對應的組件類型定義如清單 3 所示(XML 格式)。
遠程服務透過入口點發布,供外部組件訪問。在服務的 Java 接口上添加 @Remotable Annotation 即可定義遠程服務。非由 Java 類定義的服務(如從 WSDL 生成的接口)預設即為遠程接口。
// 清單 4. 帶 @Remotable 的遠程服務接口
package services.payroll;
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface PayrollService {
public PayrollStatement getPayrollStatement(String employeeID);
}
// 清單 5. PayrollStatement 接口
package services.payroll;
import java.util.List;
public interface PayrollStatement {
List getPayrollDetails();
float getNetPay();
}
遠程服務採用封送技術交換複雜數據類型,使用 Web 服務綁定時傳遞 SDO 或 JAXB 數據類型,語義為按值傳遞。在實現類上添加 @AllowsPassByReference 可聲明允許按引用傳遞以優化性能。
// 清單 6. 允許按引用傳遞的遠程服務實現
package services.payrolldata;
import org.osoa.sca.annotations.*;
@Service(PayrollDataService.class)
@AllowsPassByReference
public class PayrollDataServiceImpl implements PayrollDataService { ... }
本地服務僅能由同一模組內的客戶端調用,其接口定義不使用 @Remotable Annotation。本地調用採用按引用的數據交換語義,雙方可見參數變更。
使用 @Scope Annotation 於服務接口或實現類上指定作用域,支援的範圍值包括:
除 Module 作用域外,SCA 運行時會防止其他三種作用域的實例併發執行方法。作用域服務可透過 @Init 和 @Destroy 實現生命週期方法。
// 清單 8. 會話作用域服務接口
package services.profile;
import org.osoa.sca.annotations.Scope;
@Scope("session")
public interface ProfileService {
public String getFirstName();
public void setFirstName(String pName);
// ... 其他方法
}
// 清單 9. 擁有生命週期方法的實現類
package services.profile;
import org.osoa.sca.annotations.*;
@Service(ProfileService.class)
public class ProfileServiceImpl implements ProfileService {
@Init
public void start() { ... }
@Destroy
public void stop() { ... }
}
在 Java 類的字段或方法上使用 @Property Annotation 定義配置屬性,屬性包括 name(預設為字段名)和 required(是否必須注入,預設 false)。
// 清單 10. 配置屬性與引用注入範例
package services.payroll;
import org.osoa.sca.annotations.*;
public class PayrollServiceImpl implements PayrollService {
@Property
private String currency = "INR";
@Reference
private PayrollDataService payrollDataService;
public PayrollStatement getPayrollStatement(String employeeID) { ... }
}
客戶端可從 SCA 組件或非 SCA 組件獲取服務訪問權限。
主要透過引用注入:在類中定義服務接口類型的字段,並標註 @Reference Annotation。屬性包括 name(引用名稱)和 required(是否必須注入)。
// 清單 11. 使用 @Reference 注入
package services.profile;
import org.osoa.sca.annotations.*;
@Service(LoginService.class)
public class LoginServiceImpl implements LoginService {
@Reference(name="profileService", required=true)
private ProfileService profileService;
public int login(String employeeID, String passWord) { ... }
}
對應的組件類型 XML 定義見清單 12。
非注入方式可透過 ModuleContext 查找服務。需先注入 ModuleContext(或使用 @Context),再調用 locateService(String serviceName) 方法。CurrentModuleContext.getContext() 提供靜態獲取當前模組上下文的途徑,適用於非 SCA 組件(如 Servlet)。
// 清單 14. Servlet 中使用 CurrentModuleContext
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp) {
LoginService loginMgr = (LoginService) CurrentModuleContext.getContext()
.locateService("LoginServiceComponent");
// ...
}
}
屬於 SCA 模組一部分的非 SCA 組件同樣使用 ModuleContext 查找服務,透過 CurrentModuleContext.getContext() 獲取上下文實例。
ServiceRuntimeException 和 ServiceUnavailableException。SCA 支援三種異步調用類型:
@Oneway Annotation,適用於返回 void 且無拋出異常聲明的方法。@Scope、@Session、@SessionID 管理會話狀態,簡化長時間運行的交互。@Callback 指定回調接口,實現雙向異步通信。// 清單 16. 回調接口範例
@Remotable
@Callback(MyServiceCallback.class)
public interface MyService {
void someMethod(String arg);
}
@Remotable
public interface MyServiceCallback {
void receiveResult(String result);
}
Apache Tuscany(孵化中)提供 SCA 運行時實現,主要參與者包括 IBM、BEA、Oracle、Sybase、SAP、IONA、Siebel 等。
本文系統闡述了 SCA Java 實現模型的核心概念:服務表示與實現、配置屬性、客戶端訪問模式(引用注入、模組上下文)、錯誤處理及異步編程機制,為開發基於 SCA 的 Java 應用奠定基礎。