OSGi 基本原理

2024-02-08 05:32
文章标签 基本原理 osgi

本文主要是介绍OSGi 基本原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定义


OSGi(Open Service Gateway Initiative)技术是面向Java的动态模型系统。

这个框架实现了一个优雅、完整和动态地组价模型。应用程序(称为bundle)无序重新引导可以被远程安装、启动、升级和卸载。

OSGi服务平台提供在多种网络设备上无需重启的动态改变构造的功能。

为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供一种面向服务的架构,它能使这些组件动态地发现对方。

OSGi联盟已经开发了例如像HTTP服务器、配置、日志、安全、用户管理、XML等很多公共功能标准组件接口。这些组件的兼容性插件实现可以从进行了不同优化和使用代价的不同计算机服务提供商得到。然而,服务接口能够基于专有权基础上开发。

OSGi的主要职责就是为了让开发者能够创建动态化、模块化的Java系统。

 

OSGi 框架


OSGi框架从概念上可以分为三层:模块层、生命周期层和服务层。

  • Module Layer:模块层主要涉及包及共享的代码;
  • Lifecycle Layer:生命周期层主要涉及Bundle的运行时生命周期管理;
  • Service Layer:服务层主要涉及模块之间的交互和通信。
图 1. OSGi 层次结构

 

模块层


模块层是 OSGi 框架中最基础的部分。

OSGi 的模块化,是通过为 Jar 包添加metadata 来定义哪些类该暴露,哪些类该隐藏,其控制单元叫做 Bundle(jar 包)。

Bundle

首先,必须先了解一个基本概念——什么是Bundle?

什么是 Bundle ?
bundle 是以 jar 包形式存在的一个模块化物理单元,里面包含了代码,资源文件和元数据(metadata),并且jar包的物理边界也同时是运行时逻辑模块的封装边界。
bundle

 

如何定义 Bundle

Bundle 是 OSGi 中的基本组件,其表现形式仍然为 Java 概念中传统的 Jar 包。
通过 META-INF 目录下的 MANIFEST.MF 文件对其予以进一步的定义。

通常一个 MANIFEST.MF 文件的内容如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Util
Bundle-SymbolicName: com.ibm.director.la.util
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.ibm.director.la.util;uses:="org.osgi.framework"
Bundle-ClassPath: lib/junit.jar,

MANIFEST.MF 文件存储的实际上是 Bundle 的元数据。

元数据的内容可以精确的定义 Bundle 的各种特征,同时能更好的对 Bundle 进行标识同时帮助用户对Bundle进行理解。

 

生命周期层


 

生命周期层在OSGi框架中属于模块层上面的一层,它的运作是建立在模块层的功能之上的。
生命周期层的主要功能是控制动态安装、开启、关闭、更新和卸载的bundles。

生命周期层让你能够从外部管理应用或者建立能够自我管理的应用(或者两者的结合),并且给了应用本身很大的动态性。

前面已经了解了 Bundle 的概念和作用。但是要真正使用 Bundle,需要使用生命周期层的API,来和OSGi框架的生命周期层进行交互。

在标准的Java编程中,可以通过将jar包放到classpath中来使用它。而bundle则不是这样,Bundle只有在被安装(install)到一个OSGi框架的运行实例中才能用起来。并且OSGi框架支持对这些bundle完整的生命周期管理,并且支持这些管理操作在应用执行完成。

下图为 Bundle 生命周期的状态转移图:

 

http://assets.osgi.com.cn/article/7289216/lifecycle2.png

 

重要接口

生命周期层的API主要是由以下三个核心接口来组成的:BundleActivator,BundleContext 和 Bundle。
  • BundleActivator:让你能够捕捉bundle的start和stop事件,并对这两个事件作出自定义的反应。
  • BundleContext:一个bundle在框架中的执行时上下文,这个上下文提供了和框架进行交互的方法。
  • Bundle:在逻辑上表示了一个bundle,OSGi环境中的一个物理bundle对应了一个bundle对象。该对象中包含了bundle的基本信息和bundle生命周期的控制接口。

 

服务层


 

一个OSGi 服务就是注册到 OSGi 框架中的一个 Java 对象。注册的时候可以设置这个 Service 的属性。而在获取 Service的时候可以根据属性进行过滤。

Bundle 可以通过 Bundle的上下文去注册Service或去查询Service。

一个提供服务的bundle可以发布POJO作为服务的实体;一个使用服务的bundle可以通过这个注册表找到和绑定服务。 

http://assets.osgi.com.cn/article/7289220/service1.PNG

 

发布服务

为了让别的bundle能发现这个服务,你必须在发布它之前对其进行特征描述。这些特征包括接口的名字(可以是名字的数组),接口的实现,和一个可选的java.util.Dictionary类型的元数据信息。

String[] interfaces =   new String[]{StockListing. class.getName(), StockChart. class.getname()};  
Dictionary metadata =   new Properties();  
metadata.setProperty(“name”, “LSE”);  
metadata.setProperty(“currency”, Currency.getInstance(“GBP”));  
metadata.setProperty(“country”, “GB”);  
ServiceRegistration registration = bundleContext.registerService(interfaces,  new LSE(), metadata); 
在上面的代码中,我们得到了 ServiceRegistration 对象,我们可以用这个对象来更新服务的元数据:
registration.setProperties(newMetadata);
也可以直接就把这个服务移除:
registration.unregister();
需要注意的是这个对象不能和其他 Bundle 共享,因为它和发布服务的bundle的生命周期相互依存。

也就是说,如果这个 Bundle 已经不在框架执行环境中存在,那么这个对象也不应该存在了,“皮之不存毛将焉附”就是这个道理。

试想如果这个 ServiceRegistration 共享给了其他的 bundle(具体的说就是其他bundle中存在对这个对象的引用),那么发布服务的那个bundle即使被移除了,由于其他bundle中的引用依然存在,那么垃圾处理机制不会抹去这个对象,这样不但于理不合,而且实际上这个对象也是不可用的,因为这个对象所依存的bundle已经不在了。
代码中的参数new LSE()是一个POJO,这个对象不需要实现任何OSGi类型或者使用标注,只要满足服务约定(这里就是接口)就可以了。

此外,如果在删除发布的服务之前bundle停止了,框架会帮助你删除这些服务。

 

发现和绑定服务

以下是一个根据实现的接口名称获得的服务的最简单方法:
ServiceReference reference =  
bundleContext.getServiceReference(StockListing. class.getName());

注意这里的reference是服务对象的间接引用,可是为什么要用间接引用而不直接返回那个实际的服务对象呢?

实际上是为了将服务的使用和服务的实现进行解耦,将服务注册表作为两者的中间人,达到跟踪和控制服务的目的,同时还可以在服务消失了以后通知使用者。

这个方法的返回类型是ServiceReference,它可以在bundle之间互享,因为它和使用服务的bundle的生命周期无关。

 

参考资料


 

OSGi入门篇:模块层

OSGi入门篇:生命周期层 

OSGi入门篇:服务层 

OSGi原理与最佳实践

这篇关于OSGi 基本原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/690034

相关文章

防盗链的基本原理与实现

我的实现防盗链的做法,也是参考该位前辈的文章。基本原理就是就是一句话:通过判断request请求头的refer是否来源于本站。(当然请求头是来自于客户端的,是可伪造的,暂不在本文讨论范围内)。首先我们去了解下什么是HTTP Referer。简言之,HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务

【CSS in Depth 2 精译_023】第四章概述 + 4.1 Flexbox 布局的基本原理

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

AI学习指南深度学习篇-带动量的随机梯度下降法的基本原理

AI学习指南深度学习篇——带动量的随机梯度下降法的基本原理 引言 在深度学习中,优化算法被广泛应用于训练神经网络模型。随机梯度下降法(SGD)是最常用的优化算法之一,但单独使用SGD在收敛速度和稳定性方面存在一些问题。为了应对这些挑战,动量法应运而生。本文将详细介绍动量法的原理,包括动量的概念、指数加权移动平均、参数更新等内容,最后通过实际示例展示动量如何帮助SGD在参数更新过程中平稳地前进。

Zookeeper基本原理

1.什么是Zookeeper?         Zookeeper是一个开源的分布式协调服务器框架,由Apache软件基金会开发,专为分布式系统设计。它主要用于在分布式环境中管理和协调多个节点之间的配置信息、状态数据和元数据。         Zookeeper采用了观察者模式的设计理念,其核心职责是存储和管理集群中共享的数据,并为各个节点提供一致的数据视图。在Zookeeper中,客户端(如

Filter基本原理和使用

https://www.cnblogs.com/xdp-gacl/p/3948353.html 一、Filter简介   Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控

golang学习笔记02——gin框架及基本原理

目录 1.前言2.必要的知识3.路由注册流程3.1 核心数据结构3.2 执行流程3.3 创建并初始化gin.Engine3.4 注册middleware3.5 注册路由及处理函数(1)拼接完整的路径参数(2)组合处理函数链(3)注册完成路径及处理函数链到路由树 3.6 服务端口监听 4. 请求处理5. 请求绑定和响应渲染5.1. 请求绑定5.2 响应渲染 结束语 1.前言 g

DDS基本原理--FPGA学习笔记

DDS信号发生器原理: `timescale 1ns / 1ps//// Company: // Engineer: // // Create Date: 2024/09/04 15:20:30// Design Name: hilary// Module Name: DDS_Module//module DDS_Module(Clk,Reset_n,Fword,

小琳Python课堂:Python高并发实现的基本原理(高阶版)

大家好,这里是小琳Python课堂! 今天,我们将从高阶视角深入探讨Python高并发实现的基本原理,特别是线程安全性、线程同步和原子性这三个核心概念。这些概念对于构建复杂、高效的多线程应用程序至关重要。 线程安全性 首先,让我们深入理解线程安全性。线程安全性涉及到在多线程环境中对共享资源的正确访问。在Python中,由于全局解释器锁(GIL)的存在,真正的并行执行需要通过多进程实现。然而,即

kettle源码分析之4 osgi与插件开发

文章目录 简介使用注册查找服务 插件数据库插件stepjob https://wiki.pentaho.com/display/EAI/OSGI+in+Kettle https://www.oreilly.com/library/view/building-modular-cloud/9781449345143/ 简介 对于kettle的插件系统可以看一下上面连接的文档。

Google的MapReduce和Hadoop的MapReduce基本原理

Google的MapReduce和Hadoop的MapReduce基本原理 MapReduce框架的执行过程可以概述为以下几个关键步骤: 输入分割:用户程序中的MapReduce库首先将输入文件分割成M个片段,每个片段通常大小在16MB到64MB之间,用户可以通过可选参数控制。 启动作业:程序在集群的多台机器上启动多个副本,其中一个机器作为master,其余作为worker。 任务分配