首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

SCA Java 客戶端與實現模型詳解

     編輯:Java 相關知識

引言

SCA (Service Component Architecture) Java 實現模型為在 Java 中開發 SCA 組件提供了標準化框架。組件實現既可以作為服務提供者,也可以作為其他服務的客戶端。本文將詳細說明 SCA Java 組件實現與非 SCA Java 組件如何獲取服務訪問權限並調用服務方法。文中所有元數據均採用 J2SE 5.0 的 Annotation 功能定義,但 SCA 服務客戶端與組件實現也兼容 J2SE 1.4 環境。

基本組件實現模型

該模型描述了本地或遠程服務的實現方式,以及特定於實現的配置屬性。

實現服務

服務通過接口表示,接口定義方式包括:

  • Java 接口(SCA 首選方式)
  • Java 類
  • 從 WSDL 端口類型生成的 Java 接口

Java 類組件實現需實現服務接口定義的所有操作,並使用 @Service Annotation 指定該組件作為服務實現的接口。類本身不一定需要 @Service Annotation,但若用於服務實現則建議添加。@Service 擁有兩個屬性:

  • interfaces:指定組件作為服務暴露的接口或類對象陣列。
  • value:僅提供單個服務接口時的簡寫屬性。無屬性的 @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 於服務接口或實現類上指定作用域,支援的範圍值包括:

  • Stateless(預設):每個請求獨立處理,實例可從池中獲取。
  • Request:同一遠程請求處理期間的所有本地調用委派給同一實例。
  • Session:同一會話內的所有請求委派給同一實例。
  • Module:同一模組內的所有請求委派給同一實例。

除 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 組件獲取服務訪問權限。

從 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 模組一部分的非 SCA 組件同樣使用 ModuleContext 查找服務,透過 CurrentModuleContext.getContext() 獲取上下文實例。

錯誤處理

  • 業務異常:由服務方法實現拋出。
  • SCA 運行時異常:由運行時拋出,指示組件管理或遠程交互問題,包含 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 應用奠定基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved