osgi容器_使用“蓝图容器”规范构建OSGi应用程序

osgi容器

OSGi框架(为开发模块化和动态应用程序提供了很好的机制)已经越来越流行。 最新的OSGi服务平台第4版V4.2规范引入了一个称为“蓝图容器”的规范。

蓝图容器规范定义了OSGi的依赖项注入框架。 它旨在处理OSGi的动态性质,在该性质下服务可以随时变得可用和不可用。 该规范还旨在与普通的Java对象(PO​​JO)一起使用,以便可以在OSGi框架内外使用相同的对象。 定义和描述应用程序各种组件的Blueprint XML文件是Blueprint编程模型的关键。 该规范描述了如何实例化组件并将它们连接在一起以形成一个正在运行的应用程序。

蓝图容器规范使用扩展程序模式,扩展程序捆绑包监视框架中捆绑包的状态,并根据其状态代表这些捆绑包执行操作。 蓝图扩展程序束等待束被激活,然后检查它们是否为蓝图束。 当一个捆绑包包含一个或多个Blueprint XML文件时,该捆绑包被视为Blueprint捆绑包。 这些XML文件位于OSGI-INF / blueprint /目录下的固定位置,或在Bundle-Blueprint清单标头中明确指定。

扩展程序确定捆绑包是​​Blueprint捆绑包后,便代表该捆绑包创建一个Blueprint容器。 蓝图容器负责:

  • 解析蓝图XML文件
  • 实例化
  • 将组件连接在一起

在初始化期间,蓝图容器确保满足强制性服务引用,将所有服务注册到服务注册表中,并创建初始组件实例。 当捆绑包停止时,Blueprint扩展程序捆绑包还会破坏该捆绑包的Blueprint容器。

本文重点介绍Blueprint XML。 通过几个示例,学习有关组件XML定义及其用法的信息。

蓝图XML

蓝图XML文件由顶级blueprint元素标识,如清单1所示。

清单1.蓝图XML文件片段
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns=”http://www.osgi.org/xmlns/blueprint/v1.0.0”>
    ...
</blueprint>

蓝图XML文件包含各种组件管理器的定义。 蓝图容器规范定义了四个主要的组件管理器:一个bean管理器 ,一个服务管理器和两个服务引用管理器 。 每个经理负责创建和管理他们创建的组件的生命周期。 当询问时,管理器提供一个组件实例。 每个管理器都有一个描述该管理器属性的对应XML元素。 经理可以是顶级经理,也可以内联在其他经理定义中。 经理们也有一些共同的属性。

  • id :定义经理ID。 id属性是可选的。 如果未指定,则将自动生成一个唯一的ID,并将其分配给顶层管理员。 内联管理器被视为匿名管理器,不允许设置id属性。 蓝图容器中所有顶级管理者的管理者ID必须唯一。 使用这些ID,以便管理者可以相互参考。 例如,在注入期间,管理器将要求引用的管理器提供将被注入到管理器正在创建的组件中的对象。
  • activation :此可选属性定义管理器的激活模式。 支持两种激活模式:
    • eager ,在“蓝图容器”初始化期间激活管理器。
    • lazy ,其中按需激活管理器。

    默认情况下,采用eager激活模式。 但是,可以通过在blueprint元素上设置default-activation属性来更改Blueprint XML文件中所有管理器的默认激活模式。 当要求管理器提供其第一个组件实例时,将激活该管理器。 销毁蓝图容器时,将停用管理器。 每个管理员都有自己的激活和停用步骤。

  • dependsOn :此可选属性指定管理器ID的列表。 在激活管理员之前,将首先激活列出的管理员。 管理器可以具有显式和隐式依赖性。 dependsOn属性定义显式依赖项。 隐式依赖关系是通过在管理器定义中对其他管理器的引用来定义的。

豆经理

Bean管理器使用给定的参数和属性创建Java对象的实例。 Bean管理器可以根据作用域设置创建单个或多个对象实例。 它还可以管理对象的生命周期,并在注入所有属性或销毁对象时通知它。

在Blueprint XML中, bean元素定义了bean管理器。 用于对象构造的参数由argument元素指定; 注入的属性由property子元素指定。

在对象构造期间,蓝图容器必须首先找到正确的构造函数或带有与XML中指定的参数匹配的兼容参数集的工厂方法。 默认情况下,蓝图容器使用XML中argument元素的数量和顺序来查找正确的构造函数或方法。 如果argument元素不能按照其顺序映射到参数,则“蓝图容器”将尝试对argument元素重新排序并找到最合适的安排。

为了帮助“蓝图容器”选择正确的构造函数,方法或参数安排,可以在argument元素上指定其他属性,例如indextype 。 例如, type属性指定一个类名,该类名用于按确切类型将argument元素与参数匹配。

property元素指定要注入的属性的名称和值。 该属性名称与Java类中的setter方法名称相对应。 例如,如果属性名称为foo ,则相应的setter方法为setFoo(arg) 。 属性名称和相应的setter方法名称遵循JavaBeans规范中定义的属性设计模式。

argumentproperty元素的value可以使用valueref属性指定,也可以内联。 ref属性指定顶级管理器的ID,用于从引用的管理器获取对象作为参数或属性值。 内联值可以是“对象值”部分中描述的任何XML值。

施工

可以通过以下三种方式构造bean:

  • 一个类的构造函数
  • 静态工厂方法
  • 实例工厂方法

清单2、3和4演示了构造Java对象的三种方法。 每个清单都显示了部分Java类以及驱动对象创建的相应Blueprint XML摘录。

清单2显示了一个简单的构造函数创建示例。 在此示例中, class属性指定要实例化的Java类的名称。 蓝图容器将通过向构造函数传递1作为参数并调用setDescription()方法来注入Account属性,从而创建Account对象。

清单2.构造器示例
public class Account {      
       public Account(long number) {
          ...
       }
       public void setDescription(String description) {
          ...
       }
       public String getDescription() {
          ...
       }
   }

   <bean id=”accountOne” class=“org.apache.geronimo.osgi.Account”>
       <argument value=”1”/>
       <property name=”description” value=”#1 account”/>
   </bean>

清单3显示了静态工厂方法构造。 在此示例中, class属性指定包含静态工厂方法的类的名称。 静态工厂方法的名称由factory-method属性指定。 蓝图容器将在AccountFactory类上调用createAccount()静态方法,并传递2作为创建Account对象的参数。 一旦工厂返回创建的对象,容器将向其注入description属性。

清单3.静态工厂方法示例
public class StaticAccountFactory {      
       public static Account createAccount(long number) {
          return new Account(number);
       }
   }

   <bean id=”accountTwo” class=“org.apache.geronimo.osgi.StaticAccountFactory” 
         factory-method=“createAccount”>   
       <argument value=”2”/>
       <property name=”description” value=”#2 account”/>     
   </bean>

如清单4所示,通过实例工厂方法构造,使用了两个管理器。 一个经理是一个工厂,另一个经理则使用工厂来创建对象。 factory-ref属性用于指定顶级bean或类似于工厂的引用管理器的ID。 提供的工厂对象必须具有factory-method属性指定的factory-method

在示例中, accountFactory bean管理器是工厂。 蓝图容器将首先使用其自己的参数和属性创建AccountFactory实例。 在这种情况下,仅指定一个参数:工厂名称。 然后,蓝图容器将在AccountFactory实例上调用createAccount()方法,并传递3作为参数来创建Account对象。 一旦工厂返回创建的对象,容器将向其注入description属性。

清单4.实例工厂方法示例
public class AccountFactory {      
       public AccountFactory(String factoryName) {
          ...
       }
       public Account createAccount(long number) {
          return new Account(number);
       }
   }

   <bean id=”accountFactory” class=“org.apache.geronimo.osgi.AccountFactory”>  
       <argument value=”account factory”/>      
   </bean>

   <bean id=”accountThree”
         factory-ref=“accountFactory” 
         factory-method=“createAccount”>   
       <argument value=”3”/>
       <property name=”description” value=”#3 account”/>      
   </bean>

范围

根据作用域设置,Bean管理器可以创建单个或多个对象实例。 蓝图容器规范定义了两个主要范围:

  • singleton :bean管理器创建bean的单个实例,并在每次要求管理器提供一个对象时返回该实例。
  • prototype :每次要求管理器提供一个对象时,bean管理器都会创建一个新的bean实例。

缺省情况下,顶级bean管理器采用singleton作用域。 不能在嵌入式Bean管理器上设置scope属性,因此始终将嵌入式管理器视为具有prototype范围。

scope属性用于指定范围设置。 清单5显示了具有不同范围设置的两个bean定义。

清单5.范围示例
<bean id=”prototypeAccount” class=“org.apache.geronimo.osgi.Account” 
         scope=”prototype”>
       <argument value=”4”/>
   </bean>

   <bean id=”singletonAccount” class=“org.apache.geronimo.osgi.Account” 
         scope=”singleton”>
       <argument value=”5”/>
   </bean>

生命周期回调

Bean管理器还可以管理其创建的对象的生命周期,并可以在注入所有属性或销毁所有属性时通知它。 蓝图容器规范定义了两种回调方法:

  • init-method :指定在注入所有属性后要调用的方法。
  • destroy-method :指定当蓝图容器销毁对象实例时要调用的方法。

prototype范围内的bean不支持destroy-method回调。 销毁那些实例是应用程序的责任。 两种生命周期方法都必须是公共的,不带参数,也不返回值。

清单6显示了一个带有生命周期方法和Blueprint XML bean条目的Java类的示例,该条目指定了init-methoddestroy-method属性。

清单6.生命周期回调示例
public class Account {      
       public Account(long number) {
          ...
       }
       public void init() {
          ...
       }
       public void destroy() {
          ...
       }
   }

   <bean id=”accountFour” class=“org.apache.geronimo.osgi.Account” 
         init-method=”init” destroy-method=”destroy”>
       <argument value=”6”/>
       <property name=”description” value=”#6 account”/>
   </bean>

服务参考经理

服务参考管理器提供对在OSGi服务注册表中注册的服务的访问。 蓝图规范定义了两个服务参考管理器:参考和参考列表。

参考经理

引用管理器提供了一个对象,该对象是服务注册表中注册的实际服务的代理。 代理允许注入的对象保持不变,而后勤服务可以来去去或被其他服务替换。 没有后备服务的代理上的呼叫将阻塞,直到服务可用或发生超时为止。

参考管理器由reference元素定义。 使用timeout属性指定代理等待后备服务可用的timeout 。 如果未指定timeout属性,则假定默认超时为5分钟。 还可以使用blueprint元素上的default-timeout属性为Blueprint XML文件中的所有引用管理器更改default-timeout 。 所有超时值均以毫秒为单位; 值0表示无限期超时。

清单7显示了一个简单的引用管理器示例。 服务代理将有30秒的超时时间。

清单7.参考管理器示例
<reference id=”serviceReferenceOne” 
              interface=”java.io.Serializable” 
              timeout=”30000”/>

参考清单管理员

引用列表管理器提供一个List对象,该对象包含服务代理对象或ServiceReference对象,具体取决于成员类型设置。 所提供的List对象是动态的,因为随着从服务注册表中添加或删除匹配的服务,它可以增长和收缩。 List对象是只读的,并且仅支持List API的子集。

参考列表管理器中的代理与参考管理器中的代理不同。 它们具有固定的后备服务,没有超时,并且如果后备服务不可用,则立即抛出ServiceUnavailableException

参考列表管理器由reference-list元素定义。 使用member-type属性指定提供的List对象中member-typemember-type属性支持两个值:

  • service-object :注入默认情况下假定的服务代理对象列表。
  • service-reference :插入ServiceReference对象的列表。

清单8显示了一个简单的引用列表管理器示例。 List成员将是服务代理。

清单8.引用列表管理器示例
<reference-list id=”serviceReferenceListOne” 
                   interface=”java.io.Serializable” 
                   member-type=”service-object”/>

服务选择和代理

参考和参考列表管理器共享几个属性。 三个共享属性用于服务选择: interfacecomponent-namefilter

您可以使用interface属性来指定接口类。 接口类用于两个目的:用于服务选择和用于服务代理。 interface属性是可选的,但是如果设置,它必须指定接口类。 对于服务选择,接口类用于从使用该接口名称注册的服务注册表中选择服务。 对于服务代理,服务引用管理器返回的代理必须实现该接口类定义的所有方法。 如果未指定interface属性,则代理的行为就好像它实现了没有任何方法的接口一样。

您也可以使用component-namefilter属性进行服务选择。 component-name属性只是将osgi.service.blueprint.compname=<component-name>表达式添加到选择过滤器的便捷方法。 同样, filter属性指定要添加到选择过滤器的原始OSGi过滤器表达式。 将interfacecomponent-namefilter属性组合在一起,以创建一个用于服务选择的主要OSGi过滤器表达式。

例如,清单7中用于引用的选择过滤器是( &(objectClass=java.io.Serializable)) ,而清单9中用于引用的选择过滤器是(&(objectClass=java.io.Serializable)(osgi.service.blueprint.compname=myAccount)(mode=shared))

清单9.服务选择示例
<reference id=”serviceReferenceTwo”              
              interface=”java.io.Serializable” 
              component-name=”myAccount”
              filter=”(mode=shared)”/>

可用性

服务参考管理器可以要求至少有一个与其选择标准匹配的服务,然后才能继续进行“蓝图容器”初始化。 该需求由availability属性控制。 availability属性可以具有两个值:

  • optional :符合或不符合选择标准的服务。
  • mandatorymandatory至少存在一项符合选择标准的服务。

默认情况下,假定为mandatory可用性。 可以使用blueprint元素上的default-availability属性为Blueprint XML中的所有服务引用管理器更改默认可用性设置。

具有mandatory可用性且具有匹配服务的服务参考管理器被视为满意。 具有optional可用性的服务参考管理器始终被认为是满意的,即使它没有任何匹配的服务。 蓝图容器初始化将被延迟,直到满足所有强制性服务参考管理器为止。

重要的是要了解,仅在Blueprint Container初始化期间才考虑mandatory可用性。 初始化之后,随着服务在任何时候来去去,强制性服务引用可能变得不满意。

清单10显示了具有mandatory可用性的引用管理器的示例。

清单10.可用性示例
<reference id=”serviceReferenceThree” 
              interface=”java.io.Serializable” 
              timeout=”30000” 
              availability=”mandatory”/>

参考侦听器

两个服务参考管理器都可以具有零个或多个参考侦听器。 引用侦听器是在服务引用管理器选择服务或服务引用管理器不再使用该服务时调用了回调方法的对象。 使用reference-listener元素指定reference-listener器。 bind-methodunbind-method属性指定回调方法。 提供回调方法的对象可以内嵌在reference-listener元素中,也可以指定为对顶级管理器的引用。

绑定和取消绑定回调方法都可以具有以下任何签名。 ( anyMethod表示任意方法名称。)

  • void anyMethod(ServiceReference) :参数是绑定或未绑定的服务的ServiceReference对象。
  • void anyMethod(? super T) :参数是绑定或未绑定的服务对象代理。 类型T必须可以从服务对象中分配。
  • void anyMethod(? super T, Map) :第一个参数是绑定或未绑定的服务对象代理。 类型T必须可以从服务对象中分配。 第二个参数提供与服务关联的服务属性。

如果引用侦听器有多个用于回调的重载方法,则将调用每个具有匹配签名的方法。

对于引用列表管理器,每次在服务注册表中添加或删除匹配的服务时都会调用侦听器回调。 但是,对于引用管理器,当管理器已绑定到服务并将具有较低排名的匹配服务添加到服务注册表时,将不会调用绑定回调。 同样,绑定管理器的服务消失后,将不会调用unbind回调,并且可以立即将其替换为另一个匹配的服务。

重要的是要了解,当使用引用管理器并与有状态服务交互时,应使用引用侦听器跟踪代理的后备服务,以便适当地管理服务的状态。

清单11显示了一个简单的注册侦听器示例。 ReferenceListener类具有两个bind方法和一个unbind回调方法,当服务从服务引用列表管理器绑定和解除绑定时,将调用它们。

清单11.引用侦听器示例
public class ReferenceListener {
       public void bind(ServiceReference reference) {
           ...
       }
       public void bind(Serializable service) {
           ...
       }
       public void unbind(ServiceReference reference) {
           ...
       }       
   }

   <reference-list id=”serviceReferenceListTwo” interface=”java.io.Serializable”
              availability=”optional”>
      <reference-listener 
              bind-method=”bind” unbind-method=”unbind”>
          <bean class=“org.apache.geronimo.osgi.ReferenceListener”/>        
      </reference-listener>
   </reference-list>

服务经理

服务管理器在OSGi服务注册表中注册服务。 如果满足其依赖项中的所有强制性服务引用管理器,则服务管理器将注册和注销该服务。 由于强制服务引用在任何时候都可能变得不令人满意,因此服务管理器将返回一个ServiceRegistration代理对象,该对象将调用委派给实际的ServiceRegistration对象。

在初始化期间,蓝图容器为蓝图容器中的每个服务管理器而不是实际的服务对象注册基于ServiceFactory的服务。 这些服务允许“蓝图容器”延迟对象的创建,因为它们拦截服务请求并仅在需要时实例化实际的服务对象。 实际的服务对象由另一个管理器(通常是bean管理器)提供。 实际的服务对象可以实现OSGi ServiceFactory接口。

在Blueprint XML中, service元素定义了服务管理器。 可以使用ref属性引用提供服务对象的管理器,也可以将其内联到service元素中。 清单12显示了两种服务:一种具有引用的服务,另一种具有内联管理器。

清单12.服务管理器示例
<service id=”serviceOne” ref=”account” ... />

   <service id=”serviceTwo” … >
      <bean class=“org.apache.geronimo.osgi.Account”>
          <argument value=”123”/>
      </bean>
   </service>

服务接口

每个服务都必须使用一个或多个接口名称进行注册。 服务的接口名称列表可以显式指定,也可以基于自动导出设置从服务对象自动确定。 可以使用以下任一方式显式设置接口名称:

  • interface属性,只能指定一个接口名称。
  • interfaces子元素,允许设置任意数量的接口。

自动导出设置由auto-export属性指定,并支持以下四个选项。

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

清单13显示了使用三种指定服务接口的方法的服务。 在此示例中,使用一个Serializable接口类注册serviceOneserviceTwo服务,而使用MyAccountAccountSerializable类注册serviceThree服务。

清单13.服务接口示例
public class MyAccount extends Account implements java.io.Serializable {
       ...
   }

   <bean id=”myAccount” class=”org.apache.geronimo.osgi.MyAccount”>
       <argument value=”7”/>
       <property name=”description” value=”MyAccount”/> 
   </bean>

   <service id=”serviceOne” ref=”myAccount” interface=”java.io.Serializable”/>

   <service id=”serviceTwo” ref=”myAccount”>
      <interfaces>
          <value>java.io.Serializable</value>
      </interfaces>
   </service>

   <service id=”serviceThree” ref=”myAccount” autoExport=”all-classes”/>

服务属性

服务也可以使用可以使用service-properties子元素指定的一组属性进行注册。 service-properties元素包含代表各个属性的多个entry子元素。 使用key属性指定属性键,但是可以将属性值指定为value属性或在元素内联。 服务属性值可以具有不同的类型,但仅允许使用基元,基元包装器类,集合或基元类型的数组。

清单14显示了具有两个服务属性的服务注册的示例。 active服务属性的值是java.lang.Boolean类型。 mode属性为String类型。

清单14.服务属性示例
<service id=”serviceFour” ref=”myAccount” autoExport=”all-classes”>
      <service-properties>
          <entry key=”mode” value=”shared”/>
          <entry key=”active”>
              <value type=”java.lang.Boolean”>true</value>
          </entry>
      </service-properties>
   </service>

如果为服务提供服务对象的管理器是顶级管理器,则会将osgi.service.blueprint.compname属性自动添加到服务属性。 osgi.service.blueprint.compname属性的值是提供服务实例的顶级管理器的ID。 例如,给定清单14中的服务示例, osgi.service.blueprint.compname属性的值将设置为myAccount

服务排名

您可以使用ranking属性来为服务提供特定的排名。 如果未指定等级属性,则该服务将不进行等级注册。 在这种情况下,OSGi框架将0假定为服务的默认排名。

带有排名的服务注册示例如下所示。

清单15.服务排名示例
<service id=”serviceFive” ref=”myAccount” auto-export=”all-classes” ranking=”3”/>

注册监听器

服务管理器可以具有零个或多个注册侦听器 ,这些对象具有在服务注册之后或注销服务之前立即调用回调方法的对象。 使用registration-listener子元素指定registration-listener器。 registration-methodunregistration-method属性指定回调方法。 提供回调方法的对象可以内联在registration-listener元素中,或指定为对顶级管理器的引用。

注册和取消注册回调方法的签名取决于服务对象是否实现ServiceFactory接口。 如果服务实现ServiceFactory接口,则这两个方法都必须具有void anyMethod(ServiceFactory, Map)签名,其中anyMethod表示任意方法名称。

如果服务未实现ServiceFactory接口,则这两个回调方法都必须与void anyMethod(? super T, Map)签名匹配,在该签名中,可以从服务对象的类型中分配类型T。 回调方法的第一个参数是服务对象的实例,第二个参数是注册属性。 如果注册侦听器有多个用于回调的重载方法,则将调用每个具有匹配签名的方法。

清单16显示了一个简单的注册侦听器示例。

清单16.注册侦听器示例
public class RegistrationListener {
       public void register(Account account, Map properties) {
           ...
       }
       public void unregister(Account account, Map properties) {
           ...
       }
   }

   <service id=”serviceSix” ref=”myAccount” auto-export=”all-classes”>
      <registration-listener 
              registration-method=”register” unregistration-method=”unregister”>
          <bean class=“org.apache.geronimo.osgi.RegistrationListener”/>         
      </registration-listener>
   </service>

环境经理

蓝图容器规范还定义了许多特殊的环境管理器,这些管理器已设置ID并提供对环境组件的访问。 它们没有XML定义,因此不能被覆盖,因为它们的ID是保留的,不能与其他管理器一起使用。 由环境管理员提供的对象只能使用引用注入到其他管理员中。 蓝图容器规范定义了四个环境管理器:

  • blueprintBundle :提供包的Bundle对象。
  • blueprintBundleContext :提供捆绑软件的BundleContext对象。
  • blueprintContainer :为BlueprintContainer包提供BlueprintContainer对象。
  • blueprintConverter :为捆绑包提供Converter对象,该捆绑包提供对Blueprint容器类型转换工具的访问。 类型转换有更多信息。

清单17显示了一个简单的示例,其中将blueprintBundle环境管理器提供的Bundle对象注入到accountManagerOne bean中。

清单17.环境管理器示例
public class AccountManager {
       public void setManagerBundle(Bundle bundle) {
           ...
       }
   }

   <bean id=”accountManagerOne” class=”org.apache.geronimo.osgi.AccountManager”>
      <property name=”managerBundle” ref=”blueprintBundle”/>
   </bean>

对象值

蓝图容器规范定义了许多XML元素,这些元素描述了不同类型的对象值。 这些XML值元素在管理器定义中使用。 例如,可以在Bean管理器中使用它们来指定参数或属性值,或者在服务管理器中使用它们来指定服务属性的值。 XML值元素将转换为实际值对象,并注入到管理器组件中。

ref元素定义对顶级管理器的引用。 component-id属性指定顶级管理器的ID。 注入的值将是引用的管理器返回的对象。

清单18显示了ref值元素的示例。 该accountOne bean实例注入managedAccount的财产accountManagerTwo豆。

清单18.参考值示例
public class AccountManager {
       ...
       public void setManagedAccount(Account account) {
           ...   
       }
   }

   <bean id=”accountOne” class=“org.apache.geronimo.osgi.Account”>
       <argument value=”1”/>
       <property name="description" value="#1 account"/>
   </bean>

   <bean id=”accountManagerTwo” class=“org.apache.geronimo.osgi.AccountManager”>
       <property name=”managedAccount”>
           <ref component-id=”accountOne”/>
       </property>
   </bean>

idref元素定义顶级管理器的ID。 注入的值是component-id属性指定的component-ididref元素用于确保在激活管理器之前实际存在指定ID的管理器。

value元素表示要根据该元素的字符串内容创建的对象。 您可以使用可选的type属性来指定字符串内容应转换为的类型。 如果未指定type属性,则字符串内容将转换为正在注入的类型。

null元素表示Java null。

listsetarray元素是集合,分别代表java.util.List对象, java.util.Set对象和Object[]数组。 这些集合的子元素可以是本节中描述的任何XML值元素。 可以在这些元素上设置可选的value-type属性,以指定集合子元素的默认类型。

清单19中的示例显示了如何将XML值元素组合在一起以创建列表。 创建的列表将包含以下四个项目:

  • 一个“ 123” String
  • 具有456值的java.math.BigInteger对象
  • 空值
  • 一个具有两个类型为java.lang.Integer值的java.util.Set对象
清单19.复杂列表值示例
<list>
       <value>123</value>
       <value type=”java.math.BigInteger”>456</value>
       <null/>
       <set value-type=”java.lang.Integer”>
           <value>1</value>
           <value>2</value>
       </set>      
   </list>

props元素表示一个java.util.Properties对象,其中的键和值是String类型的。 prop子元素代表各个属性。 使用key属性指定属性键,但是可以将属性值指定为value属性或元素的内容。

清单20显示了props value元素的示例。

清单20. Properties值示例
<props>
        <prop key=”yes”>good</prop>
        <prop key=”no” value=”bad”/>       
    </props>

map元素表示一个java.util.Map对象,其中键和值可以是任意对象。 entry子元素代表各个属性。 键可以指定为key属性, key-ref属性,也可以内联在key子元素中。 该值可以指定为value属性, value-ref属性或内联。 可以将内联值指定为本节中描述的任何XML值元素。 但是,可以将内联键指定为除null元素之外的任何XML值元素。 蓝图规范中的map元素中不允许使用空键。 key-refvalue-ref属性指定顶级管理器的ID,并用于从指定的管理器获取对象作为属性键或值。 map元素可以指定key-typevalue-type属性,以定义键和值的默认类型。

清单21显示了map值元素的示例。 它还显示了如何以几种方式构造map对象的条目。 创建的map对象将包含以下条目:

  • 一个myKey1 String键,它映射到myValue String
  • 作为account Bean管理器返回的对象的键被映射到myValue String
  • 一个键(它是一个具有123值的java.lang.Integer对象)被映射到myValue String
  • myKey2 String键映射到一个值,该值是account bean管理器返回的对象。
  • myKey3 String键映射到一个值为345的java.lang.Long对象的值。
  • 一个键是urn:ibm值的java.net.URI对象,它映射到一个值是http://ibm.com值的java.net.URL对象。
清单21. map值示例
<map>
       <entry key=”myKey1” value=”myValue”/>

       <entry key-ref=”account” value=”myValue”/>
       <entry value=”myValue”>
           <key>
               <value type=”java.lang.Integer”>123</value>
           <key/>
       </entry>

       <entry key=”myKey2” value-ref=”account”>
       <entry key=”myKey3”>           
           <value type=”java.lang.Long”>345</value>          
       </entry>

       <entry> 
           <key>
               <value type=”java.net.URI”>urn:ibm</value>
           <key/>
           <value type=”java.net.URL”>http://ibm.com</value>
       </entry>
   </map>

每个经理也可以作为值内联。 清单22显示了一个内联的bean管理器示例。

清单22.内联管理器值示例
<bean id=”accountManagerThree” class=“org.apache.geronimo.osgi.AccountManager”>
       <property name=”managedAccount”>
           <bean class=“org.apache.geronimo.osgi.Account”>
               <argument value=”10”/>
               <property name="description" value="Inlined Account"/>
           </bean>
       </property>
   </bean>

类型转换

在注入期间,蓝图容器将XML值元素转换为实际对象。 它根据注入的属性的类型转换元素。 例如,在清单2中 ,Blueprint容器将123 String值转换为long值。 蓝图容器提供了许多内置转换,例如转换:

  • 将字符串值分为所有原始类型,包装器类型,或具有采用String值的公共构造函数的任何类型。
  • array元素放入集合对象(具有兼容的成员类型)。
  • set元素listset为数组对象(具有兼容的成员类型)。

蓝图容器还支持泛型。 如果泛型信息可用,则蓝图容器将使用该信息来执行转换。 例如,在清单23中, list元素将被转换为java.util.Long对象的列表。

清单23.泛型转换示例
public class AccountManager {      
       ...
       public void setAccountNumbers(List<Long> accounts) {
          ...
       }
   }

   <bean id=”accountManagerFour” class=“org.apache.geronimo.osgi.AccountManager”>
       <property name=”accountNumbers”>
           <list>
               <value>123</value>
               <value>456</value>
               <value>789</value>
           </list>
       </property>
   </bean>

除了内置的转换,Blueprint捆绑包还可以提供自己的转换器。 定制转换器是Bean管理器,提供了实现Blueprint的Converter接口的对象。 自定义转换type-convertersblueprint元素下的type-converters元素内指定。 The type converters are initialized first during Blueprint Container initialization so other managers can take advantage of the custom converters. The Blueprint Container specification has more information about writing custom converters.

Experimenting with Blueprint

To experiment with Blueprint applications, you need two things: an OSGi platform and the Blueprint Container implementation. In this article, we will use Equinox as the OSGi platform, but others — such as Apache Felix — would work just as well. For the Blueprint Container, we will use an implementation from the Apache Aries incubator project. The Blueprint implementation in Aries was originally developed at the Apache Geronimo project, but has been moved to Aries, where it is being actively developed.

The attached sample provides a good starting point for experimenting with Blueprint. It contains two modules: blueprint-sample and blueprint-assembly . The blueprint-sample module is a sample Blueprint bundle. It contains many of the Java classes and Blueprint XML definitions shown in this article. The blueprint-assembly module packages the Equinox framework, the Apache Aries Blueprint implementation, and the sample bundle together in an easy-to-start container.

Building the sample

Download and unzip the attached sample source to a directory of your choice. Use Apache Maven to build the sample source. Execute the commands in Listing 24 to build the sample.

Listing 24. Building the sample
cd sample
mvn install

Maven will automatically build both modules in the sample. Once the entire sample is successfully built, the target directory of the blueprint-assembly module will contain a number of JAR files. It will contain the Apache Aries Blueprint implementation, the sample bundle and a couple other JARs that provide logging capabilities for the OSGi framework. It will also contain the osgi-3.5.0.v20090520.jar file, which provides the Equinox framework. Once started, the Equinox framework will automatically install and start all the other JARs in the target directory. To start the Equinox framework, execute the commands in Listing 25.

Listing 25. Starting Equinox
cd blueprint-assembly/target
java -jar osgi-3.5.0.v20090520.jar -console

The Equinox console will appear after successful startup. Use the ss command to display the installed bundles; Figure 1 shows the output of the ss command.

Figure 1. Installed bundles output
The Equinox console appears after successful startup

Running the sample bundle

The sample bundle will be automatically installed in Equinox framework, but will not be started. To start the sample bundle, execute the start 5 command in the Equinox console; the number 5 is the ID of the org.apache.aries.sample_1.0.0.SNAPSHOT sample bundle. Once the sample bundle is successfully started, you should see the following output in the console, as shown in Figure 2.

Figure 2. Sample bundle output
Once the sample bundle is     successfully started, this output will appear in the console

摘要

The Blueprint Container specification, introduced in the latest OSGi specification, provides a simple and easy programming model for creating dynamic applications in the OSGi environment without adding complexity to the Java code. With the Aries Blueprint Container implementation, you can start building Blueprint-based applications today.


翻译自: https://www.ibm.com/developerworks/opensource/library/os-osgiblueprint/index.html

osgi容器

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值