月蚀传说

浮躁让人失去理智
posts - 25, comments - 101, trackbacks - 0, articles - 0
  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理

SCA程序设计——本地服务的定义以及使用

Posted on 2006-08-11 14:23 Dart 阅读(1739) 评论(9)  编辑  收藏 所属分类: SCA

1.       SCA 简介

2005 11 月, IBM BEA Oracle SAP 等国外著名企业联合发布了 SCA 0.9 规范草稿。 SCA 是一种全新的、跟语言无关的编程模型,这种面向服务构件的编程模型可以大大简化客户的编程,提高应用的灵活性,将会对现有软件开发方式产生颠覆性的影响。”上面段文字是摘自普元 SCA 中文论坛中对 SCA 的描述,大家可以通过上面简短的文字对 SCA 有一个简单的认识。

SCA 全称 Service Component Architecture (服务组件构架) , 它是一套遵循 SOA 思想的构架,通过模型描述来构建应用系统。 SCA 并不只是针对于一种语言,它是可以支持多种语言的( Java,C++,PHP…. ),目前 SCA 给出了 Java 以及 C++ 的实现规范。

对于 Java 版本的 SCA ,可以通过配置文件以及 J2SE5.0 Annotation 功能来描述服务,或者是通过 XML 格式的配置文件来描述服务,并能使得 SCA 容器对其进行管理。

以下文中所提到了 SCA 都是 Java 版本的 SCA

SCA 中的服务可以分为本地、远程服务,以及外部服务,服务具有自己的属性、引用,并且通过一些表示,可以确定服务的生命周期。

下面介绍一下如何定义本地服务,以及如何去调用本地服务。

2 .简单的本地服务

SCA 中可以通过 J2SE5.0 Annotation 来对服务进行标记,利用 @Service 标签,就可以定义一个服务,一般情况下,服务一般是一个接口类,服务实现是一个具体实现该接口的类,当然,我们也可以把一个具体的类定义为一个服务,服务实现即其本身。

@Service 标记是放在实现类上使用的,当标记上后, SCA 容器就会认为这个实现类为服务的实现。而服务的描述则是通过 @Service 的值来指定的,请看下面代码:

@Service(TestService. class )
public   class  TestServiceImpl  implements
 TestService {

    
public   void
 invoke() {
        System.out.println(
" invoke method "
);
    }

    
public   void
 print(String printString) {
        System.out.println(
" print  "   +
 printString );
    }

}


上面代码的将 TestServiceImpl 上标记了 @Service 而@Service中的TestService.class值就表明了该服务接口即为TestService接口,而TestServiceImpl就是这个服务的实现。通过上面简单的定义,一个简单的本地服务就算是做好了。

这是最简单的本地服务例子, @Service 中的服务接口仅仅只有一个,如果我们想要去调用这个服务则需要启动 SCA 容器,然后通过模型上下文去定位服务:

              

 SCA sca  =   new  UxTeamSCA(); 

              sca.start(); 

              TestService service 
=  (TestService)CurrentModuleContext.getContext().locateService( " TestService "
); 

              service.invoke(); 

              service.print(
" print it "
); 


简单说一下上面代码。

SCA OSOA 组织提供的 SCA 框架标准接口,它初始化后会将当前线程中的模块上下文( ModuleContext ,也是 SCA 的一个标注接口)赋值,用户可以通过 CurrentModuleContext 类的静态方法去获得这个 ModuleContext ,模块上下文实例就可以去通过服务名定位这个服务。

我们通过 Annotation 标记服务的时候是不能给出服务名的,这种标记方式会将服务接口名默认为服务名。
 

3 .多个服务接口

在上面我们使用的 @Service 的值只有一个,其实 @Service 可以定义多个服务接口,形式如下: @Service(interfaces={Interface1.class,Interfaces2.class.....}) ,这种描述方式可以一次性定义多个服务,当然了,服务实现也还只是一个而已。

下面代码展示了如果定义多个服务:

@Service(interfaces = {TestService1. class ,TestService2. class }) 

public   class  TestServiceImpl1  implements
 TestService1 , TestService2 { 

  

       
public   void
 invoke() { 

              System.out.println(
" example2 invoke method "
); 

       } 

  

       
public   void
 print(String printString) { 

              System.out.println(
" print  "   +
 printString ); 

       } 

  




这种标记的话,
SCA 容器就会识别出 2 个服务: TesrService1 TestService2

            

  ModuleContext context  =  CurrentModuleContext.getContext(); 

  TestService1 service1 
=  (TestService1) context.locateService( " TestService1 "
); 

              service1.print(
" print it "
); 

  TestService2 service2 
=  (TestService2) context.locateService( " TestService2 "
); 

              service2.invoke(); 

 

如果我们在定义服务的时候,出现了服务定义和服务实现不一致,那就会出现异常。

注意:这里的异常并不是 SCA 标准中所提到的,因为 SCA 只给出了规范,很多厂商的实现都不太一样,对于上述问题的处理可能也不一样。在以后的章节文章中,还会出现一些这种情况,在 SCA 标准没有明确指明的情况下,我都是以个人的实现来处理的,待 SCA 完善后再进行标准处理。对于上面情况,我在实现这个简单的 SCA 容器时,将这个情况看成是异常:

@Service(interfaces = {TestService1. class ,TestService2. class }) 

public   class  TestServiceImpl2  implements
 TestService1  { 

  

       
public   void
 print(String printString) { 

              System.out.println(
" example2 print  "   +
 printString ); 

       } 

  

}
 

 

 以下调用方式会出现异常:

        TestService2 service3  =  (TestService2) context.locateService( " TestService2 " ); 

              service3.invoke(); 


4
.通过配置文件来生命服务以及实现

SCA 中可以根据配置文件来对服务进行描述。

描述服务接口的是一个后缀名为 componentType XML 文件,下面我们给出一个简单的例子:

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

< componentType  xmlns ="http://www.osoa.org/xmlns/sca/0.9" >
 

< service  name ="TestService3" >
 

< interface .java interface ="org.uxteam.sca.example3.TestService3" />
 

</ service >
 

< service  name ="TestService4" >
 

< interface .java interface ="org.uxteam.sca.example3.TestService4" />
 

</ service >
 

</ componentType >
 


上面的这个
XML 指明了服务的名称以及服务对应的接口类:

第一个服务为 TestService3 ,对应得是一个 Java 接口,接口类得全路径是 org.uxteam.sca.example3.TestService3

第二个服务为 TestService4 ,对应的是一个 Java 接口,类路径为 org.uxteam.sca.example3.TestService4

 

一般情况下,该“组件描述”文件是和实现类放在一个目录下的,文件名同实现类文件名相同,只是后缀名改为 componentType

componentType 文件只是描述了服务接口,但是服务实现并没有给出。

其实服务实现的描述是在 .module 文件中给出的。

.module 文件指明在 componentType 文件中给出的服务接口的实现类,如下:

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

< module  xmlns ="http://www.osoa.org/xmlns/sca/0.9"
 

name
="scaexample"   >
 

< component  name ="TestService3" >
 

< implementation .java class ="org.uxteam.sca.example3.TestServiceImpl" />
 

</ component >
 

  

< component  name ="TestService4" >
 

< implementation .java class ="org.uxteam.sca.example3.TestServiceImpl" />
 

</ component >
 

</ module >
 


这个文件中,将服务名和组件名对应了起来,比如第一个组件是
TestService3 ,它是一个 Java 实现,并且类路径是 org.uxteam.sca.example3.TestServiceImpl 。同理,第二个组件也如此。

我在实现这个简单的 SCA 容器时规定, module 文件必须放置在 bin 目录下(当然,其他的 SCA 容器如何规定我就不得而知了)

SCA 容器启动得时候,会去解析这几个文件,如果文件无误,那 SCA 就会开始维护配置文件中定义得服务了。我们同样可以去定位、调用这些服务:

             

 SCA sca  =   new  UxTeamSCA(); 

            sca.start(); 

            ModuleContext context 
=
 CurrentModuleContext.getContext(); 

            TestService3 service 
=  (TestService3)context.locateService( " TestService3 "
); 

            service.invoke(); 

              

           TestService4 service1 
=  (TestService4)context.locateService( " TestService4 "
); 

           service1.execute(); 


5
.结束语

通过上面的介绍希望能让网友们对 SCA 有一个比较清晰简单的认识。而本人实现的 SCA 容器目前来说还很幼稚,我会随着对该 SCA 文章的更新来完善我的 SCA 容器。我本人希望能借此文章抛砖引玉,各位达人请多多指点,有错误的地方还请大家指正。

下一章节我们来讲服务的属性和引用 
代码第一部分下载
代码第二部分下载
代码第三部分下载


评论

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-08-14 11:26 by Long Long Ago
原来那些gef的文章怎么没有了

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-08-15 11:12 by guangqing
Apache tuscany是SCA/SDO的runtime的开源实现,楼主的容器可以参考下它啊

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-08-15 11:29 by guangqing
针对你公开多个服务的情况,我写了一个component的impl,不知道你的容器会不会报错
@Service(TestService1.class)
public class TestService3 implements TestService1 {

private TestService2 testService2;

public void setTestService2(TestService2 testService2) {
this.testService2 = testService2;
}

public void print(String printString) {
this.testService2.invoke();
}

}

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-08-15 13:05 by Dart
@guangqing


Apache的那个项目我看了下,它有C++的实现,并且对于SCA0.9中和EJB,JCA,Spring之间好像都有整合,但是参考它的代码话可能会很费时间,还是自己写吧,呵呵

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-08-15 13:06 by Dart
@guangqing

你定义的那个服务在我实现的容器中应该没什么问题吧,不过我传上去的例子中,对定义重复的服务没有检测

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-09-11 17:21 by aju
恕我浅薄,我没有看出它的优势所在,
这种实现根ioc有什么实质性的区别吗?

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-09-11 17:48 by Dart
回 aju:

SCA是一套完整的SOA实现框架,目前版本是0.9,还在进一步完善当中,它是一个能让“SOA落地”的框架。

IoC依赖注入是从程序设计着眼,它将实现了和接口分开,实现了松耦合。同样,SCA在某些实现采用这种方式(或者说是模式)——其实并不只是SCA框架,很多框架也都采用了IoC的思想。就是说,IoC在SCA中是被采用的技术思想之一。

本人的几篇随笔里,只是讲了SCA最基本的功能。本人的文笔较烂,再加上我对SCA的理解还不够深入,无法让读者理解其真正的用途所在,在这里我自我检讨一下,过几天我会写一篇关于如何使用SCA(SOA)进行项目开发的短文,希望能讲SCA出现的用意说明白。

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-09-11 22:29 by guangqing
说白了IoC其实就是用来管理程序之间的依赖关系
SCA中component之间的依赖关系也是由容器通过配置文件在运行时注入
也就是说IoC其实并不是SCA的一个很大的特点
SCA宣称它是SOA 的programming model
也就是依照SCA规范,就可以很好的创建SOA的服务
但从目前看
SCA做的还不够,目前的特点仅仅在于提出了一个组件模型,可以调用和提供服务,可以支持多种语言的实现,可以解决不同协议之间的消息传输等(貌似对解决遗留系统集成有不小的帮助),当然这都需要中间件的支持
但依然是component oriented
而不是service oriented

# re: SCA程序设计——本地服务的定义以及使用  回复  更多评论   

2006-09-12 08:38 by aju
那就期待搂主的文章了

只有注册用户登录后才能发表评论。


网站导航: