SCA客户端以及基于Java的模型实现(三)

本节阐述了如何从SCA组件和非SCA组件访问SCA服务,以及如何调用服务的方法。

  客户端基本模型

  本节阐述了如何从SCA组件和非SCA组件访问SCA服务,以及如何调用服务的方法。

  从组件实现访问服务

  以下的小节描述了获取服务的两种方式:

  •   使用引用注入
  •   使用模块上下文

  引用注入是推荐的方式,因为这将让代码中的API调用最小。另一种方法一般只在引用注入不可用的情况下使用

  使用引用注入

  通过引用注入获取服务的方法,是通过以一个服务接口定义和一个@Reference 标签标注一个Java类的字段。

  @Reference标签拥有以下属性:

  •   name – 引用的名称,默认是Java类属性的名字
  •   required – 服务注入或服务是否是必须的

  以下代码使用@Reference标签定义Java实现中的服务引用定义的例子。引用的名字为 “helloService”,引用的类型为HelloService。clientMethod() 调用了helloService引用的服务上的”hello”操作。

package services.client;
import services.hello.HelloService;
import org.osoa.sca.annotations.*;
@Service(ClientService.class)
public class ClientServiceImpl implements ClientService {
@Reference(name="helloService", required=true)
private HelloService helloService;
public void clientMethod() {
String result = helloService.hello("Hello World!");

}
}
以下代码以上组件实现的组件定义。组件的类型不需要在这里指明,因为可以通过Java类反射信息得到。

<?xml version="1.0" encoding="ASCII"?>







  如果引用是一个数组或是java.util.Collection, 则默认组件类型的multiplicity属性根据@Reference 的required属性为true还是false分别是为1..n 或 0..n。

  以下代码为在Java实现中使用标签@Reference标注类型java.util.List的属性为一个服务应用的定义的例子。该服务引用的名字是”helloServices”,类型为HelloService。方法clientMethod() 调用了该服务引用所引用的所有的服务的”hello”操作。在这个例子中,至少要有一个HelloService存在, 所以 required 属性为 true。

package services.client;
import java.util.List;
import org.osoa.sca.annotations.*;
import services.hello.HelloService;
@Service(ClientService.class)
public class ClientServiceImpl implements ClientService {
@Reference(name="helloService", required=true)
private List helloServices;
public void clientMethod() {

HelloService helloService = (HelloService)helloServices.get(index);
String result = helloService.hello("Hello World!");

}
}

  以下代码为上述构件实现的构件类型定义。组件的类型不需要在这里指明,因为可以通过Java类反射信息得到。

<?xml version="1.0" encoding="ASCII"?>







使用模块上下文

  如果一个组件需要访问的服务只有在运行时才能知道它的名字,那么该服务只能从ModuleContext中获得。

  为了使用模块上下文访问一个服务,那么我们需要做两件事情:

  •   1. 必须定义一个字段,用以注入模块上下文。
  •   2. 必须调用注入的模块上下文的一个方法。

  模块上下文的注入是通过添加一个类型为ModuleContext 字段并以@Context

  标签加以标注。被注入的上下文的类型是由字段的类型决定的;在这里,即是ModuleContext。

  以下代码为Java接口ModuleContext和它的locateService() 方法。

package org.osoa.sca;
public interface ModuleContext {

Object locateService(String serviceName);
}

  locateService() 方法有一个服务名称的输入函数,返回一个可访问该服务的对象。返回的这个对象实现了服务对应的Java接口。

  服务的名字必须定义在同一个SCA模块中。服务的名称可以是如下两种之一:

/

  o 如果仅定义了一个服务,则service-name是可选的

  以下代码为使用@Context标签定义模块上下文的例子。
Java类中的clientMethod() 方法用到了模块上下文,并以服务名称为参数调用了它的locateService() 方法。locateService() 方法返回的对象被类型转换成服务所定义的接口的类型。

package services.client;
import org.osoa.sca.ModuleContext;
import org.osoa.sca.annotations.*;
import services.hello.HelloService;
@Service(ClientService.class)
public class ClientServiceImpl implements ClientService {
@Context
ModuleContext moduleContext;
public void clientMethod() {
HelloService helloService = (HelloService)moduleContext.locateServic("HelloService");
String result = helloService.hello("Hello World!");

}
}

  从非SOA组件实现中访问服务

  本节描述了SCA模块中的非SCA组件如何访问服务。

  使用模块上下文

  SCA模块中的非SCA的代码可以在其实现中使用ModuleContext来寻找服务。非SCA的代码如果使用了SCA模块所在的同一个类加载器或其子加载器,则也会被认为是一个SCA模块的一部分。

  以下代码为ModuleContext 的Java接口。

package org.osoa.sca;
public interface ModuleContext {

Object locateService(String serviceName);
}

  非SCA模块可以通过CurrentModuleContext类访问当前的ModuleContext,该类的定义如下:

package org.osoa.sca;
public final class CurrentModuleContext {
public static ModuleContext getContext() { … }
}
非SCA组件在其实现代码中加上下面一行来访问模块上下文:

  ModuleContext moduleContext = CurrentModuleContext.getContext();

  只要模块上下文可用,即可调用它的locateService()方法来找到所请求的服务。以下例子演示了如何在一个JSP页面中使用模块上下文得到一个服务并调用它的方法。




pageEncoding="ISO-8859-1"
import="org.osoa.sca.*, commonj.sdo.*, services.hello.*"%>




index.jsp



ModuleContext moduleContext = CurrentModuleContext.getContext();
HelloService helloService = ( HelloService)moduleContext.locateServic("HelloService");
String result = helloService.hello("Hello World!");

%>

  调用服务的方法

  在上几节中阐述了获取服务的几种方法。在取得服务后,调用服务的方法就跟调用普通Java类的方法一样。

  以下代码为调用实现了StockQuote接口的服务的getQuote方法。

package services.client;
import services.hello.HelloService;
import org.osoa.sca.annotations.*;
@Service(ClientService.class)
public class ClientServiceImpl implements ClientService {
@Reference(name="helloService",required=true)
private HelloService helloService;
public void clientMethod() {
String result = helloService.hello("Hello World!");

}
}

  如果所访问的服务的接口标记为了远程接口,则调用时使用的将会是远程的语义。方法参数和返回值都是“传值”,并且可能抛出ServiceUnavailableException异常,这是个RuntimeException。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12639375/viewspace-151146/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12639375/viewspace-151146/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值