`
raymond.chen
  • 浏览: 1437236 次
  • 性别: 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");
	}
}

 

分享到:
评论

相关推荐

    Equinox开发OSGi应用程序

    #### OSGi及框架简介 **OSGi**(Open Service Gateway Initiative)是一种用于创建模块化Java应用程序和服务的框架。它最初是为了满足嵌入式设备和家庭网关的需求而设计的,但随着技术的发展,它的应用范围已经扩展...

    OSGi 入门+进阶+实战

    5. **Blueprint或Declarative Services**:这两种是OSGi中的服务配置方式,Blueprint更接近XML,而Declarative Services使用注解,简化了服务的声明和管理。 6. **远程服务**:OSGi Remote Services允许Bundle之间...

    OSGi实战进阶篇

    - **7.2.3 Declarative Services (DS)**:介绍Declarative Services框架的概念和用途。 - **7.2.4 ConfigurationAdminService**:阐述ConfigurationAdminService如何管理配置数据。 - **7.2.5 EventAdminService*...

    Spring OSGi 入门.pdf

    同时,了解如何与其他 OSGi 组件如 Blueprint 和 Declarative Services 结合使用,提升应用的灵活性和可维护性。 总结,Spring OSGi 为开发者提供了一种强大的工具,可以在模块化、动态的环境中构建和管理 Java ...

    OSGi.in.action.ppt

    这部分可能涉及将现有的非OSGi应用重构为符合OSGi规范的模块化系统。这通常包括将代码拆分为独立的bundle,每个bundle包含特定的功能,并且可以独立更新。需要考虑服务发现、依赖管理和生命周期管理等关键因素。 3...

    osgi_programming

    Declarative Services是OSGi中用于声明式配置服务的规范。DS允许开发者在XML配置文件中声明服务的依赖关系和生命周期,而非在代码中硬编码。这样可以减少代码复杂性,提高可维护性和灵活性。在源代码中,你可以找到...

    osgi 实战 pdf

    这一部分深入探讨了OSGi的核心概念和技术细节,包括OSGi规范、ClassLoader的工作原理、Bundle的生命周期、Bundle之间的通讯机制、Declarative Services(DS)中Component的生命周期和通讯机制,以及...

    OSGI(实战中文版)

    文档通过各个章节,逐步深入到OSGi的关键部分,例如ClassLoader、Bundle的生命周期和通讯机制、DS(Declarative Services)中Component的生命周期和通讯机制等。 面向接口的开发是OSGi强调的一个重要方面,文档中...

    osgi spring实例

    2. **打包Spring应用为OSGi bundle**:将Spring应用的类和依赖打包成遵循OSGi规范的bundle,每个bundle代表一个模块。 3. **声明服务和依赖**:在MANIFEST.MF文件中声明bundle提供的服务和依赖其他服务。 4. **使用...

    OSGI中Hibernate扩展在felix中的应用

    7. **Transactions Management**:在OSGI环境中,事务管理可能需要通过Declarative Services或Blueprint等服务组件模型来实现,以协调多个bundle间的事务。 8. **Logging Integration**:Felix通常使用LogService...

    OSGI的消息机制及注册服务

    OSGI(Open Services Gateway Initiative)是一种开放标准的Java模块化系统,它允许开发人员将应用程序分解为可独立更新和管理的模块,称为“bundle”。在OSGI环境中,消息机制是实现bundle之间通信的关键部分,而...

    很久之前的osgi整理

    10. 进阶话题:可能涉及OSGi的高级特性,如felix config admin、Declarative Services(DS)或者Blueprint。 由于没有具体的文件名称列表,我们无法进一步了解压缩包的内容。通常,这样的文件可能包含示例代码、...

    equinox-1.7

    5. 服务发现与依赖注入:了解OSGi服务的概念,以及如何使用Declarative Services(DS)或Programmatic Services进行服务注册、查找和使用。 6. 日志和诊断:学习如何利用Equinox的日志系统来追踪应用程序的运行状态...

    osgi相关文档、及学习资料

    可能会包括如何创建和打包OSGi Bundle、配置Manifest文件(包含Bundle的元数据)、使用Blueprint或Declarative Services进行服务声明、理解OSGi的生命周期管理以及如何在实际项目中应用OSGi技术。 **OSGi原理与最佳...

    OSGI资料,OSGI进阶,OSGI实战,OSGI入门和整合Spring

    2. **Declarative Services(DS)**:利用OSGI的DS注解声明服务,简化Spring配置。 3. **Blueprint**:Spring的OSGI扩展,提供类似Spring XML配置的模块化服务定义方式。 4. **Aries SPI Fly**:一种用于将Spring...

    spring-osgi.jar及其依赖包

    4. **自动依赖管理**:Spring OSGi可以自动管理bundle之间的依赖关系,通过声明式服务(Declarative Services, DS)来声明服务和依赖,降低配置复杂性。 5. **集成其他Spring特性**:Spring OSGi支持Spring的AOP、...

    eclipse下构建spring与OSGI项目

    同时,可以使用Spring的Declarative Services(DS)来管理OSGi服务。 4. 编写代码:按照OSGi的模块化原则编写代码,每个模块(bundle)应尽可能独立。同时,利用Spring的特性,如DI和AOP,实现业务逻辑。 5. 测试...

    virgo-bin包

    OSGi的核心是其模块系统,每个模块称为一个“bundle”,每个bundle包含类和其他资源,有自己的类路径,并通过声明性服务(Declarative Services,DS)来实现组件之间的交互。Virgo服务器使用了Apache Felix或Equinox...

Global site tag (gtag.js) - Google Analytics