OSGI传统注册式服务与声明式服务

上一篇博文中我们编写了第二个简单的osgi的example,并编写了一个接口DictionaryService,并在Activator这个Bundle中实现了这个interface,并在start启动方法中进行了osgi服务的注册,但并没有使用这个服务,这一篇文章中并不讲解怎么使用这个已经注册的服务,但是会讲解服务的使用方式,一种为声明式服务,一种为传统注册式服务,以下就是开始讲解何为osgi的注册式服务与声明式服务。


传统注册式服务

传统方式下,我们注册服务都是在bundle的激活器(Activator)中使用BundleContext.registerService()方法完成的。而服务的获取需要通过BundleContext.getServiceReference()获取ServiceReference实例,进而使用BundleContext.getService()得到真正的服务实例。这种方式虽然能够完成服务的发布与使用,但是带来一定的问题,具体如下:

  • 产生较多的样板式代码。OSGi的bundle是动态化的,伴随着bundle的安装和卸载,它所发布的服务也会动态地处于可用或不可用的状态,因此每次使用服务的时候,我们都需要借助BundleContext对象去服务注册中心查找,而不能通过一次查找,一劳永逸地持有服务对象的引用。尽管有ServiceListener和ServiceTracker帮助我们监听和跟踪服务的状态,但是总体而言这种方式较为繁琐且容易出错。
  • 影响启动时间,服务在激活器中注册时,需要实例化所有要发布的服务对象,因为激活器的start()方法是同步调用的,所以会影响到整个应用的启动时间。
  • 加大内存的占用,在激活器中注册服务时,我们需要实例化所有的服务对象,但是这些服务在应用运行期间,并不一定会用到,这在无形中加大了内存的占用。
  • API依赖引起的平台侵入性。使用传统方式注册和使用服务,会用到大量的OSGi API,从而产生与OSGi平台的耦合,如果要将代码复用到非OSGi场景之中,需要较多的重构工作。

传统的注册式的服务写起来繁琐,并且问题比较多,因此一般都是使用声明式服务来替代,以下就开始讲解声明式服务。

声明式服务

osgi是通过声明式服务来解决以上存在的问题的,声明式服务中引入了两个元素,构件(component)和元数据文件(metadata.xml)。构件是一个物理的、可替换的系统组成部分,它包装了实现体且提供了对一组服务接口的实现方法。构件自身必须相容于接口且实现接口,接口表示了驻留在构件内的成分所实现的服务。这些服务定义了的一个整合的行为,并从一些构件实例提供给其它客户端构件实例。在声明式服务中一个构件就对应了某一个构件实现类,这个类相当于是一个pojo(普通的Java对象),在这个类中我们可以注册服务、引用服务、构件属性配置等一些满足特定需求的操作,总之构件是服务的提供者和使用者。而元数据文件则是一个xml文件,在声明式服务中所有的元数据文件名称都为metadata.xml,在这个xml文件中我们可以根据需求配置构件的一些必需信息,且所配置的这些信息必须遵循声明式服务元数据规范。

声明式服务主要由四个部分组成,声明式服务容器部分、元数据解析部分、代码织入部分和打包成声明式服务bundle的插件部分。

  • 声明式服务容器—-用来解析部署到OSGi环境中的bundle,存放所有已创建的服务构件实例和方面构件实例,并对其相应的配置信息、生命周期进行管理。
  • 元数据解析—-用来解析bundle中的元数据文件信息,使用SAX解析器将元数据文件中每一个节点的信息都解析出来,构造成构件(component)或是构件实例(instance)供声明式服务容器使用。
  • 代码织入—-针对构件实现类进行的操作,主要是在构件实现类已实现的服务接口中增加一个pojo接口(用来获取当前服务对象的构件实例,给某个字段注入值),并在相应的构件实现类基础上生成以”WC “开头的字节码文件。

    -声明式服务插件—-将构件所在工程打包成声明式服务的bundle,在打包的过程中对构件实现类进行织入、对元数据文件进行解析并增强并在该bundle的manifest文件中添加与声明式相关的头标信息。


总结

这篇文章讲解了传统的注册式服务和声明式服务,注册式服务在前面一篇的博文中有所提及,在后文中还是有相应的使用,但在声明式服务上,后文中将会使用blueprint来代替,Blueprint规范来源于Spring Dynamic Modules项目,最早出现于R4.2企业规范之中。这个到了日后讲解blueprint的时候再具体讲解这些。

时间: 2024-07-28 15:46:07

OSGI传统注册式服务与声明式服务的相关文章

Spring Cloud Eureka 分布式开发之服务注册中心、负载均衡、声明式服务调用实现

介绍 本示例主要介绍 Spring Cloud 系列中的 Eureka,使你能快速上手负载均衡.声明式服务.服务注册中心等 Eureka Server Eureka 是 Netflix 的子模块,它是一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移. 服务注册和发现对于微服务架构而言,是非常重要的.有了服务发现和注册,只需要使用服务的标识符就可以访问到服务,而不需要修改服务调用的配置文件.该功能类似于 Dubbo 的注册中心,比如 Zookeeper. Eureka

005声明式服务调用Feign

1.POM配置 和普通Spring Boot工程相比,添加了Eureka Client.Feign.Hystrix.Spring Boot Starter Actuator依赖和Spring Cloud依赖管理 <dependencies> <!--Eureka Client依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>sprin

【第三章】声明式服务调用(Feign)

当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻.那么有没有更好的解决方案呢?答案是确定的有,Netflix已经为我们提供了一个框架:Feign. Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单.Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数.格

Spring Cloud 声明式服务调用 Feign

一.简介 在上一篇中,我们介绍注册中心Eureka,但是没有服务注册和服务调用,服务注册和服务调用本来应该在上一章就应该给出例子的,但是我觉得还是和Feign一起讲比较好,因为在实际项目中,都是使用声明式调用服务.而不会在客服端和服务端存储2份相同的model和api定义.Feign在RestTemplate的基础上对其封装,由它来帮助我们定义和实现依赖服务接口的定义.Spring Cloud Feign 基于Netflix Feign 实现的,整理Spring Cloud Ribbon 与 S

干货分享微服务spring-cloud(5.声明式服务调用feign)

Spring cloud feign基于Netflix feign实现,整合了spring cloud ribbon与spring cloud hystrix,除了提供这两者的强大功能之外,它还提供了一种声明式的web服务客户端定义方式 新建spring boot工程并命名为demo-springcloud-feign-consumer,新建启动类FeignApplication,通过@ EnableFeignClients注解来开启spring cloud feign的功能支持 定义YhqSe

Spring Cloud第七篇 | 声明式服务调用Feign

本文是Spring Cloud专栏的第七篇文章,了解前六篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cloud第二篇 | 使用并认识Eureka注册中心 Spring Cloud第三篇 | 搭建高可用Eureka注册中心 Spring Cloud第四篇 | 客户端负载均衡Ribbon Spring Cloud第五篇 | 服务熔断Hystrix Spring Cloud第六篇 | Hystrix仪表盘监控Hy

SpringCloud无废话入门03:Feign声明式服务调用

1.Feign概述 在上一篇的HelloService这个类中,我们有这样一行代码: return restTemplate.getForObject("http://hello-service/hello",String.class); 对于代码有一定洁癖的你来说,一定感觉到了,这个url应该是可以被配置的.既然说到配置,那我们首先想到的就是使用java注解的方式.Feign就是这样一个注解框架,它也是netflix为我们提供的,方便我们整合ribbon和hystrix(后面会学习)

Spring Cloud 入门Eureka -Consumer服务消费(声明式Feign)(三)

Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单.我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定.它具备可插拔的注解支持,包括Feign注解.JAX-RS注解.它也支持可插拔的编码器和解码器.Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现. 1.pom.xml,这里有所不同depen

Jenkins教程——从安装到部署Docker服务(二)声明式流水线HelloWorld

前言 本文通过一个声明式流水线的HelloWorld程序做一下流水线基础入门,对常用的流水线参数进行简要说明 什么是流水线 现实中的流水线 流水线比较好理解,类比于现实生活中的生产流水线,每个流程只做一件事,通过传送带把这些流程连接在一起,一个流程完成后的结果交由后续流程继续操作. Jenkins的流水线简单认知 Jenkins的流水线也是这样工作的,最简单的认知是它可以把若干可通用的Shell脚本像胶水一样连接起来,虽然这个比喻比较形象,但这只是流水线的冰山一角. Jenkins流水线的两种形