`
raymond.chen
  • 浏览: 1419487 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Declarative Services规范简介及应用

    博客分类:
  • OSGi
阅读更多

        Declarative Services 是一个面向服务的组件模型,它制订的目的是更方便地在OSGi服务平台上发布、查找、绑定服务,对服务进行动态管理,如监控服务状态以及解决服务之间的复杂的依赖关系等问题。Declarative Services采用服务组件的延迟加载以及组件生命周期管理的方式来控制对于内存的占用以及启动的速度,很好的解决了传统的OSGi服务模型在开发和部署比较复杂应用时内存占用大、启动慢等问题,并且对服务组件的描述采用XML来实现,十分便于用户理解和使用。在 Declarative Services 中,Component 可以是 Service 的提供者和引用者,一个 Component 可以提供 0 至多个 Service,也可以引用 0 至多个Service,并且采用component 方式封装 Service,方便了对 Service 的复用,从开发者的角度来看,该服务组件模型简化了在 OSGi 服务平台中的编程模型。

 

一、Component Satisfied 概念介绍
       在 Declarative Services 中,一个服务组件是通过XML文件描述其相关信息的,SCR(Service Component Runtime)根据服务组件配置文件控制着组件配置的激活(Activate)和钝化(Deactivate),服务组件配置文件包括如组件的类型、组件的实现以及引用的服务等信息。

       在 Declarative Services 中,Component Satisfied 与 Component 的生命周期密切相关。如 Component 激活的前提条件之一就是 Component Satisfied,而在 Component 的运行过程中,出现 Unsatisfied 时,Component 将被钝化。主要由以下两点决定 Component 是否处于Satisfied 状态:

              1、Component 为 Enabled 状态,Component 的生命周期包含在引用它的 Bundle 应用的生命周期之内,只有在 Bundle 处于 Active 状态时,Component 才有可能为 Enabled 状态,在 Bundle处于 Stop 状态时,Bundle 中所有的 Component 都处在 Disabled 状态。Component 初始的Enabled 状态可以在服务组件配置文件中设定。

              2、Component 的配置是可以被引用和解析的,Component 中引用的 Service 也是 Satisfied 的,引用的 Service 至少有一个是处于可用状态的,或者引用的 Service 在服务组件配置文件里配置了可为 0 个可用状态的 Service。

       当上述两个条件中任何一个不满足时,组件配置将变为 Unsatisfied 状态,组件配置将被钝化。 

 

二、Component 介绍
       在 Bundle 启动时, Declarative Services 装载相应的服务组件配置文件,配置文件在MAINFEST.MF 文件的 Service-Component 属性指定,解析配置文件,获取服务组件引用的 Service ,如果判断组件 Satisfied 状态的两个条件满足时, Declarative Services 就认为这个组件是 Satisfied 的。

       Component的类型:
              1、Immediate Component
                     对于 Immediate Component,如果组件配置处于 Satisfied 状态,将会立即被激活,并且如果该配置指定了服务,那么 SCR 会注册该服务并且立即激活该服务组件。在SCR 激活组件配置时,实现服务组件类的 activate 方法将会被调用,在SCR钝化组件配置时,deactivate方法将会被调用。
              2、Delayed Component
                     对于 Delayed Component ,如果组件配置处于Satisfied状态,该组件并不会立即被激活,Declarative Services 会根据组件配置文件中的 Service 的配置,注册相应的Service 的信息,直到该服务组件被请求时, Declarative Services 才会激活该组件配置 。 Delayed Component 延迟了 Component 类的创建,当该服务组件的服务收到请求时,该 Component 类的 activate 方法才会被调用。如果一个 Component 不是 Factory Component,并且在其组件配置文件中指定了服务,组件的 immediate 属性设置为 false,那么该组件就是 Delayed Component。
              3、Factory Component
                     通过在组件配置文件中设置 Component 的 factory 属性,将 Component 声明为 Factory Component。该组件在激活后注册的是一个 Component Factory 服务,只有在调用 Component Factory 的 newInstance 方法后才会激活相应的各个组件,每一次调用 newInstance 方法,都会创建和激活一个新的组件配置。如果在组件配置文件中声明了服务,那么在该组件激活之前,声明的服务被注册。 

 

三、服务组件开发、发布

     1、下载Declarative Services的Equinox实现(如org.eclipse.equinox.ds_1.0.0.v20060601a.jar),将该文件放到Eclipse安装目录的plugins下。使用Eclipse中的Plug-in项目向导来创建一个项目(参考OSGI系列相关文章)。

 

     2、创建服务接口及服务实现类

public interface UserManager {
	public abstract String sayHello(String username);
}

 

public class UserManagerImpl implements UserManager {
	public String sayHello(String username){
		return "你好," + username;
	}
}

    

    3、在顶级目录下创建一个名为OSGI-INF的文件夹,并新建一个名为UserManager.xml的组件配置文件

<?xml version="1.0" encoding="UTF-8"?>
<component name="userManager">	
	<!-- Implementation元素定义了实现该服务接口的组件类名 -->
	<implementation class="com.cjm.bundle.UserManagerImpl"/>	
	
	<!-- Service元素定义了所提供服务的接口 -->
	<service>		
		<provide interface="com.cjm.bundle.UserManager"/>	
	</service>
</component>

 

    4、MANIFEST.MF文件内容

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: UserValidatorBundle
Bundle-SymbolicName: UserValidatorBundle
Bundle-Version: 1.0.0
Service-Component: OSGI-INF/UserManager.xml
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.cjm.bundle;version="1.0.0"

其中,Service-Component 属性指定了该 Bundle 应用的服务组件配置文件,在该配置文件中声明服务并且指定了实现该服务的组件。Export-Package 属性指定了该 Bundle 输出的共享包,该属性可以使其他的 Bundle 引用所定义的服务接口。

 

四、服务组件获取

      在 Declarative Services 中,Component 所引用的服务,称为 Target Service。在组件实现类中,有两种策略可以获得在组件配置文件里指定的 Target Service,是事件策略和 Lookup 策略。

 

      在服务组件激活的过程中,SCR 必须将组件配置文件里指定的 Target Service 绑定到组件配置中。事件策略主要适用于服务组件所引用的 Target Service 处在动态变化中。

       

     1、组件接口及实现类 

public interface UserManagerClient {
	public UserManager getUserManager();
}

 

public class UserManagerClientImpl implements UserManagerClient{
	UserManager userManager;
	
	/**
	 * 采用事件策略绑定服务。当获取当前Bundle的服务时触发该方法。
	 */
	public void bindService(UserManager userManager){
		this.userManager = userManager;
		System.out.println("UserManagerClientImpl bindService");
	}
	
	/**
	 * 采用事件策略取消绑定。当引用该Bundle服务的Bundle停止时触发该方法。
	 */
	public void unbindService(UserManager userManager){
		this.userManager = null;
		System.out.println("UserManagerClientImpl unbindService");
	}

	public UserManager getUserManager() {
		return userManager;
	}
	
	/**
	 * 采用 Lookup 策略取得服务
	 */
	public void activate(ComponentContext context){
		UserManager userManager = (UserManager)context.locateService("userManager");
		System.out.println(userManager.sayHello("美女"));
	}
	
	public void deactivate(ComponentContext context){
		System.out.println("bye bye 美女");
	}
}

    启动顺序:先调用bind方法,再调用activate方法。

    停止顺序:先调用deactivate方法,最后调用unbind方法。

 

     2、组件配置文件内容

<?xml version="1.0" encoding="UTF-8"?>
<component name="userManagerClient">	
	<implementation class="com.cjm.bundle.user.service.web.UserManagerClientImpl"/>	
	
	<service>		
		<provide interface="com.cjm.bundle.user.service.web.UserManagerClient"/>	
	</service>
	
	<!-- 
		reference元素定义了该组件所引用的服务接口。
		
		cardinality:
			0..1:可选和单个,“0或1” 
			1..1:有且仅有一个,“只有一个”  (默认) 
			0..n:可选和多个,“0到多” 
			1..n:必须或者多个,“至少一个” 

		policy:
			static(默认)  如果引用的 Target Service 发生了变化,那么组件配置会被重新装载并激活。
			dynamic   SCR在不钝化组件配置的情况下可以改变绑定的 Target Service,即调用其中的unbind和bind方法。

		target:根据属性值过滤组件服务
	 -->
	<reference name="userManager" 
		interface="com.cjm.bundle.UserManager" 
		bind="bindService" 
		unbind="unbindService" 
		cardinality="0..1" 
		policy="static"
		target="(component.version=1.0)"/>
	
	<!-- 组件属性的配置 -->
	<property name="component.version">1.0</property>
	<property name="component.canuse" type="Boolean">true</property>
	<properties entry="OSGI-INF/config.properties"/>
</component>

 

     3、MANIFEST.MF文件内容

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: UserValidatorWebBundle
Bundle-SymbolicName: UserValidatorWebBundle
Bundle-Version: 1.0.0
Service-Component: OSGI-INF/UserManagerClient.xml
Import-Package: com.cjm.bundle, org.osgi.framework;version="1.3.0"
Export-Package: com.cjm.bundle.user.service.web

   

     4、消费服务

public class TestActivator implements BundleActivator {
	public void start(BundleContext context) throws Exception {
		ServiceReference serviceReference = context.getServiceReference(UserManagerClient.class.getName());
		UserManagerClient client = (UserManagerClient)context.getService(serviceReference);
		if(client!=null){
			System.out.println("TestActivator: " + client.getUserManager().sayHello("cjm"));
		}
	}

	public void stop(BundleContext context) throws Exception {
		System.out.println("TestActivator stop");
	}
}

 

分享到:
评论

相关推荐

    declarative

    declarative services

    Pure Declarative Programming in Swift, Among Other Things.zip

    Pure Declarative Programming in Swift, Among Other Things.zip,swift中的纯声明式编程

    Declarative dependency management for Matlab.zip

    Declarative dependency management for Matlab.zip

    Declarative Chrome Extension-crx插件

    声明式Chrome扩展程序用于调试基于Siemens Active Workspace Framework的应用程序。 这提供了以下功能。 1.Declarative Inspector检查选定的DOM元素的声明性视图模型属性(动作,ctx,数据,dataProvider,i18n,...

    declarative-shadow-dom:自定义元素以声明方式创建Shadow DOM

    &lt;declarative&gt; 自定义元素以声明方式创建Shadow DOM 它应该与给出的建议紧密合作演示版安装使用安装组件:$ bower install declarative-shadow-dom --save 或 。用法如果需要,内置的导入自定义元素可扩展polyfill&...

    Learning GraphQL: Declarative Data Fetching for Modern Web Apps

    Why is GraphQL the most innovative technology for fetching data since Ajax? By providing a query language for your APIs and a runtime for fulfilling queries with your data, GraphQL presents a clear ...

    Qt5Declarative_jll.jl

    Qt5Declarative_jll.jl (v5.15.2 + 0) 这是使用构造的自动生成的包。 原始的脚本可以在社区构建树上找到。 如果您有任何问题,请向Yggdrasil报告。 有关JLL软件包以及如何使用它们的更多详细信息,请参见...

    awesome-declarative-config:出色的声明式配置的应用程序和引擎列表

    令人赞叹的声明式配置的应用程序和引擎列表。 介绍 这是一个令人敬畏的应用程序列表,符合声明式配置的条件。 要了解该列表符合哪些条件,重要的是要了解声明性内容的实际含义。 声明式编程: “一种构建计算机程序...

    declarative-parser-0.1.zip

    declarative-parser.zip,将bean定义组成正则表达式的解析器,用于

    python SQLAlchemy的Mapping与Declarative详解

    主要介绍了python SQLAlchemy的Mapping与Declarative详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Python库 | wavestate.declarative-1.3.4.tar.gz

    python库。 资源全名:wavestate.declarative-1.3.4.tar.gz

    declarative_demo_f5

    这是一个通过Ansible部署F5声明性入职(DO)和应用程序服务3(AS3)扩展以声明方式提供BIG-IP的示例。 输出 高级剧本流程: 安装声明性入职 安装App Services 3 开机自检(板载BIG-IP) POST到AS3(LTM Config) ...

    OSGI in Action

    with Declarative Services 357 ■ Consuming services with Declarative Services 359 ■ Declarative Services component lifecycle 364 11.4 Summary 371 12 Advanced component frameworks 373 12.1 Blueprint ...

    Declarative Chrome Extension (v2.2)-crx插件

    1.查看日志以下选项卡有助于跟踪关键声明事件的执行流(按时间表): - ViewModel Tracer:列出应用程序中加载的视图模型 - 命令:列出执行的命令。 - 事件:列出应用程序生命周期期间发生的事件。 - 条件:列出应用...

    Declarative Chrome Extension (v2.1)-crx插件

    (注意:扩展名与AFX v4.0.0及更高版本兼容。)这提供了以下功能。 1.视图日志以下选项卡帮助您跟踪关键声明事件的执行流程(按时间顺序):-ViewModel Tracer:列出应用程序中加载的视图模型-Commands:列出执行的...

    declarative-linking-2.8.zip

    geomajas-project-sld-editor.zip,专家级sld编辑器gwt示例应用程序代码geomajas sld编辑器项目

    swift-declarative-configuration:对象的声明式配置

    通过功能配置器,您可以指定对象的修改并稍后应用修改。 还包含自我实现协议( ConfigInitializable , CustomConfigurable ),以使您可以为类型添加自定义配置支持( NSObject已经为您提供了支持)。 所有功能的...

    declarative-demos:尝试以声明方式解决编程难题

    它使用作为辅助库,其思想源于以及Kevlin Henney关于的精彩演讲怎么跑git clone https://github.com/dbagia/declarative-demos.git yarn yarn test文献资料演示下的每个文件夹都有其自己的自述文件,以解释问题,...

Global site tag (gtag.js) - Google Analytics