Gemini Blueprint参考文档 第11章 纲要服务

来源:互联网 发布:淘宝开店怎么描述小铺 编辑:程序博客网 时间:2024/05/21 01:32

11章 纲要服务

OSGi服务平台服务纲要规范定义了OSGi实现可能支持的大量额外服务。Gemini Blueprint支持额外的"compendium"命名空间,以集成这些服务。按照惯例,这个命名空间的前缀使用osgix:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"                                  

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:util="http://www.springframework.org/schema/util"

    xmlns:task="http://www.springframework.org/schema/task"

    xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium" 

                                                                                           

    xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

           http://www.springframework.org/schema/util

           http://www.springframework.org/schema/util/spring-util-3.2.xsd

           http://www.springframework.org/schema/task

           http://www.springframework.org/schema/task/spring-task-3.2.xsd

           http://www.osgi.org/xmlns/blueprint/v1.0.0

           http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-3.2.xsd

           http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium

           http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">

 

   <!-- use the OSGi namespace elements directly -->

   <serviceid="simpleServiceOsgi"ref="simpleService"

       interface="org.xyz.MyService"/>

 

   <!-- qualify compendium namespace elements -->

   <compendium:cm-propertiesid="cm"persistent-id="com.xyz.myapp"/>

</beans:beans>

1

纲要命名空间声明(绑定到osgix前缀)

2

Schema位置(命名空间的URI)

3

纲要命名空间使用的XML模式

目前这个命名空间提供对配置管理服务的支持。未来的版本可能会增加其他的纲要服务。

11.1. 配置管理

最重要的纲要服务之一就是配置管理服务(Configuration Admin),正如它的名字一样,通过OSGi服务注册表对感兴趣的bundle进行配置。Gemini Blueprint 提供对管理服务(CM)专门的支持,允许以声明的方式消费和注入配置数据。

11.1.1. 将配置服务条目以属性方式暴露

CM作为配置源的最简单的形式就是词典(Dictionary,它的键总是字符串)。在CM中,Gemini Blueprint通过cm-properties元素将条目以Properties对象暴露。最小的声明可能如下所示:

<osgix:cm-properties id="ds.cfg"persistent-id="data.source.office.1"/>

上面的配置,将配置管理的属性data.source.office.1,作为一个bean ds.cfg暴露给CM

[Note]

注意

persistent-id属性必须引用一个OSGi ManagedServicepersistent-id, 指定工厂持久id,引用ManagedServiceFactory是一个配置错误。

熟悉Springutil模式的人可能会发现<osgi:cm-properties/>元素类似于<util:properties/>

如果配置字典中不包含指定key的条目,可以指定默认的属性值。它的声明类似于Spring beans命名空间中的props元素:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:util="http://www.springframework.org/schema/util"

    xmlns:task="http://www.springframework.org/schema/task"

    xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"

 

    xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

           http://www.springframework.org/schema/util

           http://www.springframework.org/schema/util/spring-util-3.2.xsd

           http://www.springframework.org/schema/task

           http://www.springframework.org/schema/task/spring-task-3.2.xsd

           http://www.osgi.org/xmlns/blueprint/v1.0.0

           http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-3.2.xsd

           http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium

           http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">

 

   <compendium:cm-propertiesid="cfg.with.defaults"persistent-id="data.source.office.2">

      <beans:propkey="host">localhost</beans:prop>

      <beans:propkey="port">3306</beans:prop>

   </compendium:cm-properties>

默认情况下,配置管理条目中的属性值会被局部的属性值覆盖。因此,对于前面的例子,如果data.source.office.2配置包含host条目,它的值会覆盖局部定义的localhost。如果不希望发生这样的行为,使用local-override属性(默认为false)恢复合并算法,强制局部属性覆盖CM的条目。

由于cm-propertiesCM的条目以Properties方式暴露,它可以使用SpringPropertyPlaceholderConfigurerPropertyOverrideConfigurer将外部化和自定义特定环境的属性:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"

       xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

   http://www.springframework.org/schema/beans/spring-beans-4.2.xsd

   http://www.osgi.org/xmlns/blueprint/v1.0.0

   http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd

   http://www.springframework.org/schema/context

   http://www.springframework.org/schema/context/spring-context-4.2.xsd

   http://www.springframework.org/schema/mvc

   http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd

   http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium

   http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">

 

   <!-- Configuration Admin entry -->

   <compendium:cm-propertiesid="cmProps"persistent-id="com.xyz.myapp">

      <propkey="host">localhost</prop>

   </compendium:cm-properties>

 

   <!-- placeholder configurer -->

   <context:property-placeholderproperties-ref="cmProps"/>

 

   <beanid="dataSource" ...>

      <propertyname="host"value="${host}"/>

      <propertyname="timeout"value="${timeout}"/>

   </bean>

</beans>

cm-properties不会反映任何后续配置管理API对该条目的修改。即,一旦它被解析,cm-properties就会保持不变,不管这个CM条目进行什么修改。

11.1.2.托管属性

基于配置服务条目,Gemini Blueprint通过名字自动装配特定bean的属性。要使用这个特性,需要在bean定义内定义一个嵌入的managed-properties属性:

<bean id="managedComponent"class="MessageTank">

   <osgix:managed-properties persistent-id="com.xyz.messageservice"/>

</bean>

对于通过CM和特定persistent-id存储在字典中的每一个key,如果bean类具有匹配的名字的属性(遵循JavaBean约定),那么这个组件属性被依赖注入CMkey对应的值。如果上面例子中的一些类定义如下所示:

publicclass MessageTank {

  privateintamount;

  publicint getAmount() { returnthis.amount; }

  publicvoid setAmount(intamount) { this.amount = amount; }

}

pid com.xyz.messageservice下存储的配置字典中包含一个条目amount=200,那么在配置过程中,就会调用这个bean实例的setAmount方法,传入值200

如果属性值同时在配置服务的字典和组件元素的property元素声明中同时定义,那么CM中的值优先使用:

<bean id="managedComponent"class="MessageTank">

   <osgix:managed-properties persistent-id="com.xyz.messageservice"/>

   <property name="amount"value="100"/>

   <property name="threshold"value="500"/>

</bean>

因此,通过property元素指定的属性值可以作为默认值,如果CM中没有的话。

[Warning]

注意

不要在多个bundle或定义中共享persistent-id (PID),因为它们中只有一个能接收到通知。managed-properties依赖org.osgi.service.cm.ManagedService合同,这个合同授权每一个ManagedService实例必须由它自己的PID唯一标识。请参见配置服务规范,尤其是第104.3104.5节。

11.1.2.1. 配置服务运行时更新

配置服务的强大特定就是能够在运行时更新和删除条目。即,CM中存储的配置数据在bean创建完成之后,可以被更新。默认情况下,任何在创建之后的更新都会被忽略。然而,可以配置managed-properties元素的autowire-on-updateupdate-method属性来接收配置更新。

update-method指定当配置数据发生更新时调用bean的哪个方法。更新方法必须具有如下的签名:

public void anyMethodName(Map properties)

public void anyMethodName(Map<String,?> properties); // for Java 5

如果autowire-on-update设置为true(默认为false),那么容器会在每一次更新发生时自动装配目标bean。如果autowire-on-updateupdate-method都指定了,那么自动装配过程会优先进行。对于自动装配,组件类必须为组件属性提供setter方法。考虑下面的类定义:

publicclass ContainerManagedBean {

  // 将被重新注入(因为它由setter方法)

  private Integer integer;

  // 不会被注入(不存在setter方法)

  private Long waitTime;

 

  publicvoid setInteger(Integer integer) { this.integer = integer; }

}

publicclass SelfManagedBean {

 

  // 更新回调

  publicvoid updateCallback(Mapproperties) {

    System.out.println("Received properties " + properties);

    System.out.println("Props can be used as a Dictionary " + properties);

    // 更多的工作...

  }

}

和配置:

<bean id="containerManaged"class="ContainerManagedBean">

   <osgix:managed-propertiespersistent-id="labX"autowire-on-update="true"/>

   <propertyname="integer"value="23"/>

</bean>

<beanid="beanManaged"class="SelfManagedBean">

   <osgix:managed-propertiespersistent-id="labY"update-method="updateCallback"/>

</bean>

CM条目labX的任何更新都会被自动注入到已经存在的containerManaged bean实例中,而labY更新会被传递到updateCallback方法。

更新选项在下面的表格进行了总结:

11.1.托管的属性更新选项

autowire-on-update

update-method

行为

true

可选,自动装配后调用

用更新中的属性重新注入bean属性。重新注入需要锁定bean实例(同步指令)。如果锁定和重新注入策略不合适,则只考虑使用update-method方法。

false (默认)

可选

调用bean上的update-method回调,传入更新后的配置(传入一个Map对象,且可以安全的强转为一个Dictionary)。执行不锁定。

11.1.3. 托管服务工厂

配置管理服务支持“托管服务工厂”的概念(参见纲要规范第104.6节)。托管服务工厂由工厂pid唯一标识,通过工厂pid允许多个配置对象与工厂关联。与这个工厂有关的配置对象可以随时添加和移除。工厂的主要意图就是为每一个配置创建一个OSGi服务:添加一个配置条目会注册一个新的OSGi服务,移除一个配置条目就会注销一个OSGI服务。Gemini Blueprint提供了managed-service-factory元素来支持“托管服务工厂”的概念。一旦定义了这元素,与工厂pid有关的配置会自动创建或移除bean实例,这些bean实例基于模块beanCM配置会在OSGi空间注册或注销。

这听起来好像有点复杂,那么实际上它很简单,我们来看一个简单的例子:

<osgix:managed-service-factory id="simple-msf"

   factory-pid="com.xyz.messageservice"                                              (1)

   auto-export="all-classes">                                                         (2)

   <bean class="com.xyz.MessageTank"/>                                               (3)

</osgix:managed-service-factory>

1

工厂持久id(pid)

2

快捷标志,用于确定哪些接口会作为OSGi服务导出

3

Bean定义模板。对于每一个检测到的配置,则使用bean定义模板持久一个新的服务

在它最简单的形式中,managed-service-factory需要一个工厂的factory-pid,用于模板的bean定义和一些将bean实例发布为服务的信息。上面的定义主要就是指导Gemini Blueprint监视给定的工厂pid(通过专门的ManagedServiceFactory实现,参见纲要规范了解更多信息),对于与工厂pid有关的所有配置对象,创建一个新的、匿名的嵌入bean实例,并作为OSGi服务导出。这些bean实例的生命周期绑定到与配置对象有关的生命周期上。如果天机了一个新配置,则创建一个新bean并导出。如果删除了一个配置对象或与工厂pid分离,那么相应的bean实例也会被销毁。

在很多方面,managed-service-factory扮演了一个专门的服务出口商,类似于service元素,但是支持托管属性。实际上,managed-service-factory有许多服务的属性,类似于managed-properties属性,会表明bean如何被导出。

这些属性在下表中列出:

11.2. 托管服务工厂选项

名字

描述

interface

全限定类名(例如java.lang.Thread)

导入对象的全限定类名

context-class-loader

unmanaged

service-provider

当执行导出服务的操作时,上下文类加载器如何托管。默认值为unmanaged,即不托管上下文类加载器。service-provider保证上下文类加载器对于所有导出服务的bundle中的资源都是可见的

auto-export

disabled (默认)

interfaces

class-hierarchy

all-classes

允许Spring自动管理这个服务服务发布的服务接口。默认情况下,这个工具是disabled。 如果为interfaces,则导出服务发布所有Java接口。如果为class-hierarchy,则发布导出服务所有继承层次的Java类。如果为all-classes,则发布所有的类和接口

autowire-on-update

false (默认)

true

每次当更新发生时,容器是否应该自动装配目标bean。当指定为true时,容器会自动装配重新设置了属性的bean实例。如果也使用了update-method属性,自动装配过程优先执行

update-method

none (默认)

某个方法

当配置数据发生更新时,就会调用更新方法。允许目标bean自己处理更新信息。如果使用了autowire-on-update,那么在自动装配之后,再调用update-method

 

类似于service元素,当服务注册或注销时,接口和监听器都可以声明被通知。要了解更多信息。请参见第9.1.3节“控制导出服务发布接口”第9.1.10节“服务注册注销生命周期”

现在managed-service-factory选项已经解释清楚了,让我们看一个更加复杂的配置:

<bean id="queueTracker"class="org.xyz.queue.QueueTracker"/>

<osgix:managed-service-factory id="data-msf"

   factory-pid="org.xyz.labX"               (1)

   autowire-on-update="true"                (2)

   update-method="refresh">                 (3)

   <osgix:interfaces>

       <value>java.util.Collection</value>  (4)

       <value>java.util.Queue</value>       (4)

   </osgix:interfaces>

   <osgix:registration-listener ref="queueTracker"   (5)

       registration-method="track"                   (6)

       unregistration-method="untrack"/>             (7)

   <bean class="com.xyz.ResizableQueue">             (8)

       <property name="size"value="100"/>

       <property name="concurrency"value="10"/>

       <property name="fair"value="false"/>

   </bean>

</osgix:managed-service-factory>

1

ManagedServiceFactory工厂持久id

2

当配置更新时,Gemini Blueprint是否自动装配bean

3

自动接入之后调用的方法

4

嵌入bean将这些interfaces发布为OSGi服务

5

当服务(基于CM配置)注册或注销时,需要通知的监听器

6

自定义服务注册方法(可选)

7

自定义服务注销方法(可选)

8

Bean定义模板

上面的例子,为org.xyz.labX工厂id下的每一个配置条目创建了虚构的ResizeableQueue实例。每一个实例都为sizeconcurrencyfair参数赋了默认值。然而,就像managed-properties一样,在bean创建期间,来自配置管理的值会通过名字注入,可能会覆盖已有的设置。一旦创建和配置,每一个嵌入的、匿名的bean实例都以java.util.Collectionjava.util.Queue接口注册为OSGi服务。OSGi服务生命周期被注册监听器监视,即bean queueTracker。最后,由于指定了autowire-on-updateupdate-method属性,对于每一个CM配置的更新都会引发容器用新设置的属性自动装配有关的bean实例。之后,就会调用bean上面的刷新回调。

11.1.4. 直接访问配置数据

与保存在持久id和工厂持久id下面的配置数据一起工作最简单的方式,就是注册一个实现了ManagedService或者ManagedServiceFactory接口的服务。指定一个你感兴趣的pid作为服务属性(要了解更多信息,请参阅OSGi纲要规范的配置管理章节)。例如:

<osgi:service interface="org.osgi.service.cm.ManagedService"ref="myManagedService">

   <osgi:service-properties>

     <entry key="service.pid"value="my.managed.service.pid"/>

   </osgi:service-properties>

</osgi:service>

<bean id="myManagedService"class="com.xyz.MyManagedService"/>


原创粉丝点击