今天主要讲一下在osgi环境下的服务注册、和服务引用。
其实osgi只是一个java动态化、模块化的一系列规范,根据不同厂商制定了不同的规范,如Felix和Equinox则分别是Apache和Eclipse开源社区给出的标准规范的实现!而osgi的魅力也在于动态化和模块化,我个人认为要实现动态化最简单的就是通过classload动态加载。我个人理解而已,osgi只是在传统开发的基础上抽象了一个bundle组件的概念,每一个bundle组件都有自己的生命周期,bundle实现动态化是基于bundle classloader实现的。理论性的东西我不想讲太多,大家可以去看一下osgi基础方面的东西,如bundle生命周期,bundle classloader等内容。而服务的注册,服务的引用等内容恰恰是bundle生命周期最好的诠释!
先说一下osgi环境下的服务注册,其实这部分内容在第二讲的时候已经大概说过一点儿,这次我们讲解一下传统的osgi服务注册和使用框架的方式来注册等。
一个bundle被部署到osgi容器里有几个最要的阶段也可以称之为bundle的生命周期,主要包括 INSTALLED(调用BundleContext.installBundle()后,会创建一个INSTALLED状态的bundle)、RESOLVED(如果其所依赖的所有bundle都存在,即解析成功,转到RESOLVED状态)、STARTING(当开始执行BundleActivator.start(),则处于STARTING状态)、ACTIVE(当执行BundleActivator.start()成功,则转到ACTIVE状态)、STOPPING(当开始执行BundleActivator.stop(),则处于STOPPING状态)、UNINSTALLED(INSTALLED状态的bundle可以被卸载,转到UNINSTALLED状态)。
可以看到一个bundle的整个生命周期都离不开BundleActivator和BundleContext 这两个类。
BundleContext:Bundle上下文,主要功能是与OSGI容器交互,包括服务的注册,监听器的注册,获取osgi下所有发布的服务,服务的引用等功能。建议大家好好的看一下这个类。
BundleActivator:BundleActivator是osgi提供的一个获取BundleContext的接口,同时提供bundle启动和停止的处理方法。
知道这两个类我们就可以实现BundleActivator 在bundle启动的时候通过BundleContext注册服务到osgi容器里以供其它bundle调用了。
实现一个自定义的BundleActivator :
public class HelloServiceActivator implements BundleActivator { ServiceRegistration serviceRegistration; @Override public void start(BundleContext context) throws Exception { HelloService helloService = new HelloServiceImpl(); serviceRegistration = context.registerService(HelloService.class.getName(), helloService, null); } @Override public void stop(BundleContext context) throws Exception { serviceRegistration.unregister(); } }
在这个bundle启动的时候我们通过实现BundleActivator里的start方法 实例化一个服务类并通过BundleContext的registerService注册到osgi容器里,分别传入服务名称,服务实例,服务别名(可以理解为这个的tag标签),通过stop方法注销到这个服务。
完成这一步后我们还在MANIFEST.MF(Bundle元数据描述文件,定义此Bundle依赖的jar包,导入和导出的包等基础元数据)定义Bundle-Activator为我们自己的Activator
Bundle-Activator:com.osmp.demo.HelloServiceActivator
这样我们在将此bundle部署到osgi容器的时候在bundle启动的时候就会将HelloService注册到osgi容器里供别的bundle服务调用。再简单的说一下bundle服务的引用。与发布基本相同,在启动的时候通过start方法获取到bundle上下文,通过BundleContext获取ServiceReference 服务引用,再通过此类获取我们需要的服务引用,代码如下:
public class Activator implements BundleActivator { ServiceReference helloServiceReference; public void start(BundleContext context) throws Exception { System.out.println("Hello World!!"); helloServiceReference=context.getServiceReference(HelloService.class.getName()); HelloService helloService=(HelloService)context.getService(helloServiceReference); System.out.println(helloService.sayHello()); } public void stop(BundleContext context) throws Exception { System.out.println("Goodbye World!!"); context.ungetService(helloServiceReference); } }
以上部分写到一大半的时候,想找两个例子,结果发现 http://longdick.iteye.com/blog/457310 这篇文章讲的很好,大家可以看一下,我也就不再专门讲解了。
我就说一下在osmp里是怎么实现服务的注册和服务的发现和服务路由的。
osmp里服务的发布我们是通过spring-dm来发布的,代码很简单,
spring配置文件里引入spring-osgi的schema,通过 <osgi:service>标签来将服务发布到osgi容器里,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd"> <context:component-scan base-package="com.osmp.demo.service"> </context:component-scan> <bean id="jdbcDao" class="com.osmp.jdbc.support.JdbcDao"></bean> <bean id="osmp.demo.service" class="com.osmp.demo.service.TestServiceImpl" /> <osgi:service interface="com.osmp.intf.define.service.BaseDataService" ref="osmp.demo.service"> <osgi:service-properties> <entry key="name" value="osmp-demo" /> <entry key="mark" value="测试DEMO" /> </osgi:service-properties> </osgi:service> </beans>
pom.xml 里依赖
<dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-core</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency>
pom.xml将工程打包为bundle,需要使用到 maven-bundle-plugin 这个插件:
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Export-Package></Export-Package> <Import-Package> org.springframework.aop, org.springframework.aop.framework, org.springframework.cglib, org.springframework.cglib.proxy, org.springframework.cglib.core, org.springframework.cglib.reflect, org.aopalliance.aop, org.aopalliance.intercept, *;resolution:=optional </Import-Package> </instructions> </configuration> </plugin> </plugins> </build>
PS:
1、配置文件引入spring-osgi xmlns:osgi="http://www.springframework.org/schema/osgi" http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
2、osgi:service-properties 标签对应 上面讲到的context.registerService()方法的第三个参数。我的理解是给这个服务打上tag标签,以k/v键值对的形式。
3、maven-bundle-plugin打bundle时,我这里使用的servicemix作为osgi容器,已经集成了spring,此时需要将spring的包显示的引入进来。这里比较坑的是我原本以为通过*;resolution:=optional能自动的将需要依赖的包给import进来,但是试过多次发现,只有在代码里显示的import的包才会被自动的引进去,如配置文件里依赖的包是不会自动的import进来的,而且只能一级一级的import进来。
4、spring-dm 服务引用通过<osgi:reference>这里不作详讲。
上面的例子可以查看osmp-demo源码!!!!
相关推荐
《 OSGi实战》是学习OSGi的全面指导,利用与架构和开发人员相关的示例清楚地讲解OSGi概念,同时探讨了很多实践场景和技术,阐述了开发人员有多需要OSGi,怎么将OSGi嵌入其他容器中,将遗留系统移入OSGi的最佳实践,...
3. **服务导向**:OSGI的核心在于服务,书中会讲解如何通过服务接口进行通信,以及如何利用OSGI服务注册表实现服务的发布和查找。 4. **生命周期管理**:OSGI框架提供了组件的生命周期管理,包括启动、停止、更新和...
在OSGI实战教程中,首先需要了解OSGI(Open Services Gateway Initiative)是一个由众多IT公司共同制定的Java模块化标准规范,旨在实现软件组件的热插拔和服务动态管理。OSGI技术允许应用程序通过动态地安装、启动、...
OSGi 服务发布和获取方式 OSGi(Open Service Gateway Initiative)是一种动态模块化的服务平台,能够动态地管理和部署服务。OSGi 服务发布和获取方式是 OSGi 框架中的一种核心机制,用于发布和获取服务。下面将...
"OSGI实战"和"OSGI进阶"两份文档提供了深入理解OSGI的理论和实践指导,涵盖基础概念、核心API、实战案例以及高级特性,是学习OSGI的宝贵资料。其中,"OSGI实战.pdf"着重于实践操作,而"osgiopendoc2.pdf"可能包含了...
1. **开发环境搭建**:如何使用Eclipse和Equinox等工具创建和管理OSGI项目。 2. **案例分析**:通过具体的应用场景,如构建可插拔的Web服务器、数据库连接池等,展示OSGI的优势。 3. **部署与打包**:学习如何将OSGI...
为了弥补OSGi规范在应用指导方面的不足,四位活跃在OSGi开发第一线的技术专家联手打造了《OSGi... 《OSGi实战》面向OSGi规范的使用者,通过精彩的讲解和贴近实战的丰富示例,帮助读者完成“入门-进阶-提高”三级跳。
在OSGi环境中,服务是模块间通信的主要手段,而服务的发布和获取是OSGi核心概念之一。本文将深入探讨OSGi常用的服务发布和获取方式。 一、服务发布 1. **ServiceRegistration**: 当一个模块想要提供服务时,它会...
4. **felix或equinox**:Felix和Equinox是两个常用的OSGi运行时实现,它们提供了API和框架,用于构建和运行OSGi应用。 5. **Blueprint或Declarative Services**:这两种是OSGi中的服务配置方式,Blueprint更接近XML...
资源名称:OSGi实战内容简介:为了弥补OSGi规范在应用指导方面的不足,... 《OSGi实战》面向OSGi规范的使用者,通过精彩的讲解和贴近实战的丰富示例,帮助读资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
4. 开发、发布和使用Service:介绍OSGI服务的概念,如何定义、注册服务,以及服务消费者如何查找和使用服务。 5. 测试和调试:提供测试Bundle的方法,以及如何利用OSGI提供的调试工具进行问题定位。 通过这个实战...
4. **Blueprint和Declarative Services**:这两个是OSGI中常见的服务配置方式,它们提供了一种声明式的XML格式来定义和管理服务。 5. **Equinox和Felix**:这两个是OSGI的实现框架,了解它们的特性和差异,可以帮助...
4. **事件处理**:购物车操作(添加商品、结算等)可能通过发布和订阅事件的方式进行通信。 5. **动态更新**:在源码中可能会演示如何在运行时更新bundle,以实现功能的动态扩展或修复。 **学习与实践** 通过研究...
2. **服务**:OSGI提供了一个服务注册和发现机制,允许模块之间通过服务接口进行通信,而不是直接引用彼此的类。这增强了代码的解耦和可重用性。 3. **版本管理**:OSGI支持类库的多版本共存,使得不同的模块可以...
8. **实际应用案例**:书中可能会通过真实的案例,如企业级应用、嵌入式系统或云计算平台,展示OSGi在复杂项目中的应用和优势。 通过阅读《OSGi实战中文版》,读者不仅可以掌握OSGi的基本原理,还能学习到如何在...
通过学习和实践《OSGI实战及源码》,开发者可以提高构建可扩展、灵活且易于维护的Java应用的能力,尤其在大型企业级项目中,OSGI的应用可以显著提升软件的可维护性和复用性。对于想要深入了解和应用OSGI的开发者来说...
- **6.4 开发、发布和使用Service**:探讨如何在OSGi环境中开发、发布和使用Service,这是OSGi模块化的核心概念之一。 - **6.5 测试和调试**:提供关于如何测试和调试OSGi应用的具体方法和技术。 - **6.6 发布基于...
《OSGi实战》一书由BlueDavy...通过详细的知识点讲解和实战案例分析,这本书为想要掌握OSGi技术的开发者提供了宝贵的资源。无论是初学者还是有经验的开发者,都能从中获益,提升自己在模块化架构和动态服务领域的技能。