zoukankan      html  css  js  c++  java
  • OSGi Service Registery你知多少?

    1.    发布服务可以关联一些属性。

    复制代码
    <service ref="beanToBeExported" interface="com.xyz.MyServiceInterface"> 
        <service-properties> 
            <beans:entry key="myOtherKey" value="aStringValue"/> 
            <beans:entry key="aThirdKey" value-ref="beanToExposeAsProperty"/> 
        </service-properties> 
    </service>
    复制代码

    2.    每个以Spring Bean发布成服务都会有一个属性名为org.springframework.osgi.bean.name,对应的值为目标Bean的name。

    <service ref="beanToPublish" interface="com.xyz.MessageService"/>

    这个服务就会有一个属性org.springframework.osgi.bean.name,值为beanToPublish。

    3.    Spring DM引入一种Bean的作用域,叫bundle scope。当导出服务的Bean加了这个作用域后,导入这个服务的Bundle会创建一个新的服务Bean实例。

    <service ref="beanToBeExported" interface="com.xyz.MessageService"/>
    <bean id="beanToBeExported" scope="bundle" class="com.xyz.MessageServiceImpl"/>

    4.    Controlling The Set Of Advertised Service Interfaces For An Exported Service.

    当有一个Bean服务存在多个接口时,需要将接口都导出:

    复制代码
    <service ref="beanToBeExported"> 
      <interfaces> 
        <value>com.xyz.MessageService</value> 
        <value>com.xyz.MarkerInterface</value> 
      </interfaces> 
    </osgi:service>

    or
    <service ref="beanToBeExported" auto-export="interfaces"/>
    复制代码

    auto-export有四种值:

    disabled:如果 auto-export 属性未被指定,则该选项为默认值。接口列表必须使用interface 属性或 interfaces 子元素指定。
    interfaces:使用由服务类或其任何超类实现的所有公共接口注册服务。
    class-hierarchy:使用服务类或其任何公共超类注册服务。 
    all-classes:结合 interfaces 和 class-hierarchy 选项。

    注册服务的一些属性:

    depends-on:

    <service ref="beanToBeExported" interface="com.xyz.MyServiceInterface" depends-on="myOtherComponent"/>

    配置beanToBeExported服务所依赖的组件myOtherComponent初始化。

    context-class-loader:

    用于配置使用第三方的classloader来加载服务。

    ranking:

    默放为0,如果存在多个可用的服务接口,那么返回具有最大的ranking值的服务。如果ranking值相同,刚返回service id小的那个。

    <service ref="beanToBeExported" interface="com.xyz.MyServiceInterface"  ranking="9"/>

    5.    多接口服务引用

    复制代码
    <reference id="importedOsgiService"> 
      <interfaces> 
        <value>com.xyz.MessageService</value> 
        <value>com.xyz.MarkerInterface</value> 
      </interfaces> 
    </reference>
    复制代码

    这个reference的Bean是实现了MessageService,MarkerInterface接口的。

    引用服务的一些属性

    filter属性

    <reference id="asyncMessageService" interface="com.xyz.MessageService" filter="(asynchronous-delivery=true)"/>

    过滤服务属性asynchronous-delivery为true的服务。

    bean-name属性

    <osgi:reference id="messageService" interface="com.xyz.MessageService" bean-name="messageServiceBean"/>

    返回服务Bean的Id为messageServiceBean的服务。

    cardinality属性

    <osgi:reference id="messageService" interface="com.xyz.MessageService" cardinality="1..1"/>

    默认值为1..1,说明总是有一个这样的服务存在。0..1说明不需要一直存在这样一个服务。

    depends-on:

    当depends-on属性Bean实例化后,这个服务才能查找该服务。

    context-class-loader:

    与上对应。如果两边都有,最后启作用的是exporter那端的。

    timeout:

    等待服务多少秒,默认300秒。

    List,set引用服务支持属性

    interface  filter  bean-name  cardinality  context-class-loader

    cardinality取值为0..N,1..N,前面说明可以不存在,后面说明至少存在一个。

    注意:当一个Bundle暴露SubInterface接口服务,而另一个Bundle引入SuperInterface接口是不匹配的。

    当注册的服务中有接口,类等,能通过greedy-proxying创建代理访问导入服务中的的所有包含在该Bundle中类。

    复制代码
    <list id="services" interface="com.xyz.SomeService" greedy-proxying="true"/>
    for (Iterator iterator = services.iterator(); iterator.hasNext();) { 
      SomeService service = (SomeService) iterator.next(); 
      service.executeOperation(); 
      // if the service implements an additional type 
      // do something extra 
      if (service instanceof MessageDispatcher) { 
        ((MessageDispatcher)service).sendAckMessage(); 
      } 
    }
    复制代码

    6.    服务监听Service Listener:

    复制代码
    <service ref="beanToBeExported" interface="SomeInterface"> 
        <registration-listener ref="myListener" registration-method="serviceRegistered" unregistration-method="serviceUnregistered"/>
      <registration-listener registration-method="register">
        <bean class="SomeListenerClass"/>
      </registration-listener> </service>


    public void anyMethodName(ServiceType serviceInstance, Map serviceProperties);
    public void anyMethodName(ServiceType serviceInstance, Dictionary serviceProperties);
    复制代码

    ServiceType为服务接口interface,serviceProperties保存着这个服务的所有属性,兼容性考虑的话,可以选Dictionary。
    有另一种方法,不鼓励这样用,那就是实现Spring DM特定接口OsgiServiceRegistrationListener,这样做的好处是省去了声明registration-method,unregistration-method,坏处是你的类与Spring有引用关系,与JAVA简单POJO类编程。

    Dealing With The Dynamics Of OSGi Imported Services
    An example of declaring a listener that implements OsgiServiceLifecycleListener:

    <reference id="someService" interface="com.xyz.MessageService">
        <listener ref="aListenerBean"/>
    </reference> 

    An example of declaring an inline listener bean with custom bind and unbind methods: 

    复制代码
    <reference id="someService" interface="com.xyz.MessageService">
        <listener bind-method="onBind" unbind-method="onUnbind">
            <beans:bean class="MyCustomListener"/>
        </listener>
    </reference>
    复制代码

    Listener Attributes:

      ref  bind-method  unbind-mehtod

    Listener And Service Proxies:

    Spring管理这个服务,但是调用这个服务的时候实质是一个代理。这样做的原因是防止Listener持有一个服务的强引用。Lisenter感兴趣的是监听服务而不是依赖对等实例,更加关注服务接口,而不是他的身份,服务属性和服务跟踪。

    7.    服务引用可以排序

    复制代码
    <set id="myServices" interface="com.xyz.MyService" comparator-ref="someComparator"/> 
        <list id="myOtherServices" interface="com.xyz.OtherService"> 
        <comparator> 
            <beans:bean class="MyOtherServiceComparator"/> 
        </comparator> 
    </list>
    复制代码

    Comparator-ref是一个实现了java.util.Comparator接口的Bean。

    复制代码
    <list id="myServices" interface="com.xyz.MyService"> 
      <comparator><natural basis="services"/></comparator> 
    </list> 
    <set id="myOtherServices"interface="com.xyz.OtherService"> 
      <comparator><natural basis="service-references"/></comparator> 
    </set>
    复制代码

    默认提供的一些排序,详细可以去了解下。

    服务最佳实践

    1.    在listener中不要执行太长的活动,因为这个方法是同步的,太长将会影响这个listener监听其他事件。
    2.    创建自己的listener,不要引用Spring DM 的API。
    3.    如果listener重复声明bind/unbind方法,可以考虑写一个通用的可重用的Bean。
    4.    服务属性优先java.util.Map而不是java.util.Dictionary。
    5.    重载方法要小心,因为当服务类型匹配方法服务类型的时候,该方法就会执行

    public class MyListener { 
           void register(Object service, Map properties); 
           void register(Collection dataService, Map properties); 
           void register(SortedSet orderedDataService , Map properties); 
      } 

    Object type - will match all services for which the listener is triggered. This method will be always called. 
    Collection type - if this method is called, the Object method is also called. 
    SortedSet type - if this method is called, then both the Object and Collection methods are called.

    Service Importer Global Defaults

    复制代码
    default-timeout
    <beans xmlns="http://www.springframework.org/schema/beans" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns:osgi="http://www.springframework.org/schema/osgi"                                                
             osgi:default-timeout="5000">                                                                      
         <reference id="someService" interface="com.xyz.AService"/>
         <reference id="someOtherService" interface="com.xyz.BService" timeout="1000"/>
    </beans:beans> default-cardinality <beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:osgi="http://www.springframework.org/schema/osgi" osgi:default-cardinality="0..X" default-lazy-init="false">   <reference id="someService" interface="com.xyz.AService"/>

      <set id="someSetOfService" interface="com.xyz.BService"/>
      <list id="anotherListOfServices" interface="com.xyz.CService" cardinality="1..N"/> </beans:beans>
    复制代码
     
     
  • 相关阅读:
    char*,const char*和string的相互转换[转]
    1.0到2.0 的变化
    Hello项目分析
    VS上编译Lua5.1.4生成静态库
    cocos2dx 自带动画
    asp.net2.0安全性(Login系列控件)
    用js实现的对css的一些操作方法
    mapxtreme开发小结3(c#)
    asp.net页面事件执行顺序
    access与SqlServer 之时间与日期及其它SQL语句比较
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2743865.html
Copyright © 2011-2022 走看看