月蚀传说

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

SCA程序设计——服务引用以及服务属性配置

Posted on 2006-08-16 11:58 Dart 阅读(1989) 评论(0)  编辑  收藏 所属分类: SCA
1.服务属性配置

在SCA中,服务可以定义自己的属性,利用@Property标记即可,@Property标记具有两个属性参数:
1) name 属性的名称,一个服务中属性名称是唯一的,如果重复出现多次,则多出现的属性会被忽略
2) required 表示属性是否需要配置,它接受的是bool类型的值

@Property标记需要在我们定义的服务实现类中使用,而且需要标记在字段(Field)或者Setter方法上,这里需要注意的是,所谓的Setter方法就是我们使用的Javabean中定义的Setter方法,在SCA容器中,这种方法也是可以视为属性。

服务属性定义后,SCA容器在实例化服务时,会主动去初始化那些标记了@Property的字段以及方法,对于标记的字段,无论是什么样的访问关键字,甚至是private的,SCA容器也能对其进行赋植,同样Setter方法也类似。

如果我们在Java实现类中定义属性,可以像如下代码中所写那样定义:


@Service(Service1. class )
public   class  Service1Impl  implements
 Service1 {

    @Property
    
private   int
 intValue;

   @Property
    
public   void  setIntegerValue(Integer integerValue){
        
this .integerValue  =
 integerValue;
    }
}

上面代码中,分别是给字段以及一个方法标记了@Property,而如果我们将属性定义写到componentType文件中,对应上述代码同等效应的如下所示:

<? xml version="1.0" encoding="ASCII" ?>
< sca:componentType  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9" >
  
< sca:service  name ="Service2" >
    
< sca:interface  xsi:type ="sca:JavaInterface"  
                      interface
="org.uxteam.sca.example.property.Service2"/>

  
</ sca:service >
  
< sca:property  many ="false"  name ="intValue"  required ="false"  type ="int"  / >
  
  < sca:property  many ="false"  name ="integerValue"  required ="false"  
                     type
="java.lang.Integer" />

</ sca:componentType >

而在目前本人实现的SCA容器中,对于上面这种required值为false,并且没有给出默认值的属性,初始化服务实例的时候是不会将属性设值的,如果要进行属性设值,那需要修改上面的componentType代码:

<? xml version="1.0" encoding="ASCII" ?>
< sca:componentType  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9" >
  
< sca:service  name ="Service2" >
    
< sca:interface  xsi:type ="sca:JavaInterface"  
                     interface
="org.uxteam.sca.example.property.Service2"/>

  
</ sca:service >
  
< sca:property  many ="false"  name ="intValue"  required ="true"  
                   type
="int" default="100"/>

  
   < sca:property  many ="false"  name ="integerValue"  required ="true"  
                      type
="java.lang.Integer" default="1234"/>

</ sca:componentType >

这里需要注意的是,SCA规范中,对于属性值类型有一定的限制,它规定:属性值只能是Java的简单基础类型:int,short.....或者是对应的一些对象类型:Integer,String....,而对于复杂类型的值,只能是SDO类型或者是JAXB类型的。本人实现的这个容器,目前只对SDO类型做检测,对于JAXB生成的对应并不在考虑范围内。

服务的属性除了可以定义单个值外,还可以将属性值类型改成数组,或者是从Collection继承下来的java实现类型,比如ArrayList,HashSet,LinkedList等,这一类数组以及Collection接口定义的属性,在配置文件中的many值是为true的:

<? xml version="1.0" encoding="ASCII" ?>
< sca:componentType  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9" >
  
< sca:service  name ="Service2" >
    
< sca:interface  xsi:type ="sca:JavaInterface"  
                       interface
="org.uxteam.sca.example.property.Service2"/>

  
</ sca:service >

  
< sca:property  many ="true"  name ="boolValues"  required ="true"  
                   type
="boolean" default="false"/>

  
< sca:property  many ="true"  name ="stringList"  required ="true"  
                   type
="java.lang.String" default="firstString"/>

</ sca:componentType >

@Service(Service1. class )
public   class  Service1Impl  implements
 Service1 {

    @Property
    
private   boolean [] boolValues;
    @Property
    
private  List < String >
 stringList;
    
private
 Integer integerValue;
}

注意,如果我们想要利用List等Collection接口类型去定义many属性,并且我们可能给出了一个默认值,这就需要我们主动去定义Collection中类型的泛型了,如同上面代码中所写的,stringList属性是一个List类型的,而List放置的是String类型的对象。

就如上一次我们所提到的定义Java服务那样,服务属性定义也是可以从标记和配置文件中进行配置,但是如果有冲突的地方是以Java代码标记的为主。

我们对于上面的属性定义可以通过module文件定义它们,我本人认为在module文件中定义属性,在初始化设置值的时候是很重要的,因为很多情况下,module配置文件才是实例化服务的一个参考标准:

<? xml version="1.0" encoding="ASCII" ?>
< sca:module  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9"  name ="test.module" >
  
< sca:component  name ="Service1" >
    
< sca:implementation  xsi:type ="sca:JavaImplementation"  class ="org.uxteam.sca.example.property.Service1Impl" />
  
</ sca:component >
  
< sca:component  name ="Service2" >
    
< sca:implementation  xsi:type ="sca:JavaImplementation"  class ="org.uxteam.sca.example.property.Service2" />
    
< sca:properties >
      
< intValue > 100 </ intValue >
      
< floatValue > 0.01 </ floatValue >
      
< doubleValue > 0.01 </ doubleValue >
      
< longValue > 1000000 </ longValue >
      
< boolValues > false </ boolValues >
      
< stringList > firstString </ stringList >
      
< integerValue > 1234 </ integerValue >
    
</ sca:properties >
  
</ sca:component >
</ sca:module >

2.服务的引用

服务引用其实应该算是服务访问的一种方式。

服务引用其实是指在服务实现中,通过字段或者是Setter方法去引用另外一个服务。引用是利用@Reference在Java代码中注释在字段或者Setter方法上定义的,或者是在componentType文件中加入<reference>元素:

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

    @Reference(required
= true
)
    
private
 TestService1 a;
    
    
private
 TestService1 testService2;
    
    
public   void
 print() {
        System.out.println(
" TestService Print "
);
        testService2.print();
    }
    @Reference(required
= true
)
    
public   void
 setTestService2(TestService1 testService2) {
        
this .testService2  =
 testService2;
    }

}

<? xml version="1.0" encoding="ASCII" ?>
< sca:componentType  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9" >
  
< sca:service  name ="TestService" >
    
< sca:interface  xsi:type ="sca:JavaInterface"  interface ="org.uxteam.sca.example.reference.TestService" />
  
</ sca:service >
  
< sca:reference  name ="a"   >
    
< sca:interface  xsi:type ="sca:JavaInterface"  interface ="org.uxteam.sca.example.reference.TestService1" />
  
</ sca:reference >
  
< sca:reference  name ="testService2"   >
    
< sca:interface  xsi:type ="sca:JavaInterface"  interface ="org.uxteam.sca.example.reference.TestService1" />
  
</ sca:reference >
</ sca:componentType >

@Reference具有两个属性:name和required,他们的作用类似于@Property属性参数的作用。

如果定义好了@Reference,并且给出的required值为true,那SCA容器在实例化该服务的时候,会将引用服务一同实例化——尽管我们并没有给这些字段定义值。

同@Property一样,我们也可以将这些引用字段设为数组或者是Collection接口类型。如果将服务定义的引用体现在module文件中,是如下所写:

<? xml version="1.0" encoding="ASCII" ?>
< sca:module  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:sca ="http://www.osoa.org/xmlns/sca/0.9"  name ="t" >
  
   < sca:component  name ="TestService1" >
    
< sca:implementation  xsi:type ="sca:JavaImplementation"  class ="org.uxteam.sca.example.reference.TestService1Impl" />

  
</ sca:component >
  
< sca:component  name ="TestService" >
    
< sca:implementation  xsi:type ="sca:JavaImplementation"  class ="org.uxteam.sca.example.reference.TestServiceimpl" />
    
< sca:references >
      
< a > TestService1 </ a >
      
< testService2 > TestService1 </ testService2 >
    
</ sca:references >
  
</ sca:component >
</ sca:module >

从上面的文件可以看出,设置引用的时候,引用服务的值就是某个服务的name值,如果我们在设置引用的时候,并没有将该引用类型设置为服务,在本人实现的SCA容器中,是无法对引用实例化的。

在实例化引用时,其实就是在实例化一个服务,这就会出现如下面的特殊情况:

引用出现环状 比如A引用B,B应用了C,C又引用了A

如果是这种引用,那在没有任何对服务生命周期管理的情况下,或者说服务都是无状态的(关于服务的生命周期会在以后的章节中讲述),也就是说,没实例化一个服务,那它的引用也会重新实例化。

那如果在环状引用的情况下,不难看出,会出现死循环的情况。而真对这种情况,本人实现的SCA容器会提示环状引用的出现,并且将整个引用环的最后一个节点的引用设置为NULL

3.小结

在SCA中,服务的属性定义和引用和Spirng的Bean管理极其相似,但是也有不同的地方。在SCA中,服务除了作为一个单独的功能节点存在外,它和其他服务之间的引用也是很重要的,这使得服务并不是纯粹意义上的独立,服务和服务之间建立起了一定的联系。服务属性的定义为动态初始化服务实例提供了可能。不管是服务属性还是服务引用,他们都是采用了依赖注入的思想,通过注入来获得更多的灵活性和扩展性。

本人水平有限,如有错误的地方还请达人指点。

代码第一部分下载
代码第二部分下载
代码第三部分下载

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


网站导航: