您的位置:首页 > 其它

SCA概念与应用实践(7.SCA装配模型--7.2 实现 implementation)

2010-06-25 01:03 603 查看
7.2. 实现 implementation
这个对应规范SCA Assembly Model V1.00(http://www.osoa.org/display/Main/Service+Component+Architecture+Specifications) 的1.4节

7.2.1. 解释
每个component都应该有一个implementation,它是实现具体业务逻辑的地方。所有component对外提供的service,component的reference对外的引用,component自己内部的逻辑都在这里实现。一个composite也可以是implementation。
Tuscany支持java,bpel,script等很多实现。也就是说component的implementation可以用java代码写,也可以用script来写。
打开Restaurant2.composite,就可以看到component的定义。

<sca:component name="RestaurantServiceComponent">
<sca:implementation.java class="restaurant2.lib.RestaurantServiceImpl"/>
<sca:service name="RestaurantService">
<sca:interface.java interface="restaurant2.api.RestaurantService"/>
</sca:service>
<sca:reference name="menuService"/>
<sca:reference name="billService"/>
</sca:component>
在component下有一个子元素implementation
<sca:implementation.java class="restaurant2.lib.RestaurantServiceImpl"/>
这个表示这个component是java实现的,类名是restaurant2.lib.RestaurantServiceImpl。

7.2.2. 改变implementation
前面说component可以使用其他的实现,现在我们用前面的例子演示一下使用script 实现VatServiceComponent。
在diagram中删掉component VatServiceComponent的实现,选中左上角那个图标,然后右键,选择Delete from Model.



图7_2_1

然后添加script implementation,使用palette来添加。因为在工具条上有两个Add ScriptImplementation,一个是FraSCAti运行环境的,一个tuscany运行环境,要选后者。点Script(Tuscany),然后再点在VatServiceComponent上。



图7_2_2



图7_2_3

在properties的script中填入restaurant2/lib/VatServiceImpl.js



图7_2_4

在目录 src/restaurant2/lib 添加新文件 VatServiceImpl.js.内容为:



var vatRate=10
function getPriceWithVat(price) {
return price * vatRate/100 + price;
}
[/code]

运行client,结果为,之前的价格是65.78. 因为这里我们定义的vatRate不同了。




图7_2_5

现在我们再看Restaurant2.composite文件,VatServiceComponent的定义变为
<sca:component name="VatServiceComponent">
<tuscany:implementation.script script="restaurant2/lib/VatServiceImpl.js"/>
<sca:service name="VatService">
<sca:interface.java interface="restaurant2.api.VatService"/>
</sca:service>
</sca:component>

修改之前的样子是
<sca:component name="VatServiceComponent">
<sca:implementation.java class="restaurant.lib.VatServiceImpl"/>
<sca:service name="VatService">
<sca:interface.java interface="restaurant.api.VatService"/>
</sca:service>
</sca:component>

这个implementation是可以自己定义新的implementation,而且一定会自己定义。在系统实施之前一定预先开发出一些implementation,这样在实施的时候可以减少大部分的代码工作。

7.2.3. Component Type
service,reference和property是在实现里可配置的方面。SCA将这三个东西的配置整体叫做component type。他们的属性在component定义里描述。通过component type,实现可以声明他包含的service,reference和property,同时实现也能为所有service,reference和property的属性设置值。
service,reference和property的属性都可以通过implementation对应的component的配置来覆盖,component也可以决定并不覆盖那些属性。某些属性是不能覆盖的,比如意图。



图7_2_6

做个简单的例子,说明什么是component type。
7.2.3.1. 演示例子
Ø 创建一个component,叫做HelloWorldServiceComponent



图7_2_7

Ø 添加java implementation,class name是helloworld.HelloWorldImpl
Ø Helloworld.composite内容
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:hw="http://helloworld" name="helloworld" targetNamespace="http://helloworld">
<component name="HelloWorldServiceComponent">
<implementation.java class="helloworld.HelloWorldImpl"/>
</component>
</composite>
Ø 添加接口类

package helloworld;

import org.osoa.sca.annotations.Remotable;

/**

* This is the business interface of the HelloWorld greetings service.

*/

@Remotable

public interface HelloWorldService{

public String getGreetings(String name);

}


Ø 实现类

package helloworld;

import org.osoa.sca.annotations.Property;

import org.osoa.sca.annotations.Service;

/**

* This class implements the HelloWorld service.

*/

@Service(HelloWorldService.class)

public class HelloWorldImpl  {

@Property

private String welcomeMsg = "You are welcome, ";

public String getGreetings(String name) {

return welcomeMsg +  name;

}

}


Ø 测试类

package test;

import helloworld.HelloWorldService;

import org.apache.tuscany.sca.host.embedded.SCADomain;

public class Client {

public static void main(String[] args) throws Exception {

SCADomain scaDomain = SCADomain.newInstance("helloworld.composite");

HelloWorldService hwService = scaDomain.getService(

HelloWorldService.class, "HelloWorldServiceComponent");

String msg = hwService.getGreetings("Neo");

System.out.println("====" + msg );

scaDomain.close();

}

}


Ø 运行client。

输出为====You are welcome, Neo



图7_2_8

7.2.3.2. 例子说明
在实现类HelloWorldImpl里,
@Service(HelloWorldService.class)
@Property
这两个就是component type定义,一个是定义service,一个是定义Property。他是通过java的annotation来实现。其他类型的实现,有其他的方式定义。这里演示的只是针对java implementation. 再去看Helloworld.composite的定义,你会发现这个component的定义只有implementation,没有service的定义。但我们在测试类里可以获得service,那个这个service就是implementation类HelloWorldImpl通过 @service 定义的。如果删掉@Service(HelloWorldService.class),再运行client,你会看到:
Exception in thread "main" org.osoa.sca.ServiceRuntimeException: No matching operation for getGreetings is found in service HelloWorldServiceComponent#HelloWorldImpl

7.2.3.3. component的配置来覆盖Implementation中定义
在component上定义属性welcomeMsg。
Ø 在palette上选择property



图7_2_9

Ø 添加到component上,命名为welcomeMsg



图7_2_10

Ø 设置值为How are you,



图7_2_11

Ø 运行client,
输出结果变为====How are you,Neo



图7_2_12

7.2.4. .componentType文件
7.2.4.1. 说明
前面提到一个component type由service,reference,property组成。Component type是通过两步来确定。第一步是inspection方式,SCA自己通过代码中的annotation来计算获得component type,像前面的Service的定义。。第二步是解决那些通过第一种方式不可能定义的情况,或者通过第一种方式不能定义完整的信息,第二步是第一步的补充。在理想的情况下,component type是通过第一步完全定义。第二步是通过一个.componentType文件来实现定义。 SCA在解析component的时候,如果.componentType文件存在,会同时解析这个文件。在component type文件定义的Component type信息必须与从inspection方式获得的信息兼容。

7.2.4.2. 例子
拿前面那个project继续。前面我们测试过,如果删掉HelloWorldImpl里的@service,运行时就会抛出No matching operation Exception。下面我们通过.componentType文件来定义component type。
Ø 删掉HelloWorldImpl里的@service
Ø 添加.componentType文件,在package helloworld上右键,选择【new > other】,选择SCA Component Type,点next



图7_2_13

Ø 在file name上填 HelloWorldImpl.componentType, 这个文件的名字一定要和实现类的名字相同。点finish



图7_2_14

Ø Eclipse会自动打开component type编辑器



图7_2_15

Ø 填入
<service name="HelloWorldImpl">
<interface.java interface="helloworld.HelloWorldService"/>
</service>



图7_2_16

Ø 运行client,得到结果



图7_2_17

这里你可能注意到service的名字是HelloWorldImpl,这个目前只能是这个名字,原则上讲这个可以定义其他名字,但tuscany目前这里有个问题。在tuscany的实现里,当构建runtime的component的时候,如果一个实现类没有定义@service,那么它自动加一个service给component,名字为实现类的名字。所以如果在.componentType里定义了另外一个serivce名字,tuscany会抛出一个exception:More than one service is declared on component HelloWorldServiceComponent. 另外tuscany对componentyType中的property定义也有问题,无法获得componentyType文件中定义的property的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: