1 什么是模块化
模块层是OSGi框架中最基础的一部分,其中Java的模块化特性在这一层得到了很好的实现。但是这种实现与Java本身现有的一些模块化特性又有明显的不同。 本文介绍模块层的一些基础知识,以及OSGi联盟在设计模块层时所做的一些考虑。OSGi标准走到今天,并不是凭空想出来的,它的产生恰恰是为了弥补之前一些技术的缺陷。
模块化其实就是计算机科学中常见的一个概念: “将一个大型系统分解为多个较小的互相协作的逻辑单元,通过强制设定模块之间的逻辑边界来改善系统的维护性和封装性”。
在OSGi中模块的定义可以参考下图:
也就是说一个模块(module)定义了一个逻辑边界,这种模块本身精确的控制了哪些类是完全被封装起来的,而哪些类需要暴露出来作为外部使用。这样我们就可以轻松的将实现屏蔽在模块的内部,而将公共API暴露在外部。
2 为什么需要模块化
2.1 OSGi中模块化与面向对象的联系与区别
按照以上模块化的定义,可能有的人会问:“在面向对象里面,不是也有对模块化的支持吗?”没错,面向对象的概念可以说也在一定程度上支持模块化编程,那为什么还需要OSGi提供的模块化特性呢?这涉及到“逻辑边界”的不同粒度。
在用Java编写面向对象程序的时候,一个了解面向对象概念的人是不会把所有功能都塞到同一个类里面去的,面向对象让你从问题域中发现多个事物,并且每个事物负责不同的功能,尽量做到高内聚和低耦合。在这里,我们可以说面向对象的模块化粒度是在“类”这个级别上。
而OSGi的模块化,则是通过为JAR包添加metadata来定义哪些类应该暴露哪些类又隐藏在包中,其控制可见性的粒度是在bundle(JAR包)这一层面上的。
所以,它们所带来的能力都是通过控制可见性和可用性来保证高内聚和低耦合的,但是粒度不同,一个是对象层面上的,一个是模块层面上的。 既然负责的是不同的粒度,那么两者并不相互冲突,各有各的作用在里面。
2.2 Java在模块化方面的局限性
2.2.1 底层代码可见性控制
Java提供了private,public,protected和package private(无修饰符)这四种访问控制级别,不过这仅仅提供了底层的OO数据封装特性。包这个概念确实是起到了分割代码的作用,但是如果包中的代码需要对包外可见,那么必须设置为public(或者protected,如果是使用了继承的话)。 这样的话就可能出现一个问题:
首先大家看看下面的例子,其中有三个java文件:
org.serc.helloworld.Hello.java:定义了一个接口
package org.serc.helloworld;publicinterfaceHello{void sayHello();}
org.serc.helloworld.impl.HelloImpl.java:实现了Hello接口
package org.serc.helloworld.impl;import org.serc.helloworld.Hello;publicclassHelloImplimplementsHello{finalString helloString;publicHelloImpl(String helloString){this.helloString = helloString;}publicvoid sayHello(){System.out.println(this.helloString);}}
org.serc.helloworld.main.Main.java
package org.serc.helloworld.main;import org.serc.helloworld.Hello;import org.serc.helloworld.HelloImpl;publicclassMain{finalString helloString;publicstaticvoid main(String[] args){Hello hello =newHelloImpl(“Hello,SERC!”);
hello.sayHello();}
}
这三个文件分别在不同的包中。按理说,HelloImpl这个实现细节是不应该暴露给其他包的,但是从Main.java的main方法中我们可以明显的看出,为了创建Hello 的实例,我们不得不引入HelloImpl类,但是HelloImpl作为接口的实现细节,是不应该暴露给使用者的,这违反了封装的原则,显然不太好。
但是,如果我们不想让HelloImpl暴露出来的话,就需要做额外的工作来保证“既隐藏了实现细节,又能简单的创建一个实现了Hello接口的实例”。达到这一目的的方法不止一种(比如工厂模式),有些至今也是很常用的,但是这增加了与应用本身功能无关的多余工作,想想如果你每次想开发一个应用都要为了达到上述目的而做出多余工作,不得不说是有点繁琐的,所以这可以说是Java的一大局限。
2.2.2 classpath的局限
我们在classpath中加入jar包的时候,只是简单的给出文件路径,而这个jar包的版本和一致性,它所依赖的jar包是什么,我们都无法在classpath中明确的设置或是从classpath中看出这些属性。
并且classpath中的jar包是按序加载的,例如:
classpath=c:\servlet2.2\servlet.jar;c:\servlet2.3\servlet.jar,
那么在实际应用的过程中,Java让你使用的是servlet2.2,而不是servlet2.3。这种情况下我们还能看出来使用的是哪个版本,如果在大型系统中大家分开开发的时候各用各的servlet包,并且版本号不一样,那么在最后将开发结果合并的时候,到时候用的是哪个版本的servlet包就很难搞清楚了,也就说不可控性是比较强的。
即使classpath能注意到版本的问题,也没法精确指出依赖。试着回想你在设置classpath的过程中出现过情况:在你以为classpath已经设置完毕以后,你尝试启动程序,结果虚拟机抛出异常告诉你缺包,然后你再加上你觉得缺少的那些包,然后再启动程序,如此反复直到虚拟机不运行到缺包异常为止。
2.3 OSGi对这些局限性的改善
对于上一小节提到的Java的局限,在OSGi中都得到了很好的解决。
- 包的可见性:OSGi通过引入包的可见性机制,能够完全控制一个包中的代码对哪些模块可见,而不仅仅局限于无差别的可见性,从而完善了Java的代码访问控制机制。
- 包的版本: OSGi通过为包增加版本信息,可以精确控制代码的依赖,保证代码的版本一致性,弥补了classpath的缺点。
3 OSGi模块层基础
3.1 Bundle的概念
这是模块层最核心的概念,也是模块(module)这个概念在OSGi中的具象表现。接下来你将会在OSGi的世界中创建和使用数不胜数的bundle。
什么是bundle?——bundle是以jar包形式存在的一个模块化物理单元,里面包含了代码,资源文件和元数据(metadata),并且jar包的物理边界也同时是运行时逻辑模块的封装边界。
一个更为直观的说明:在标准的jar包的manifest文件中添加一些bundle的模块化特征(就是前面提到的metadata)后,这个jar包就变成了一个bundle。
那么有了上面的描述,你大概也能想到,bundle和普通jar包最大的区别就在于元数据。
3.2 使用元数据来定义bundle
Bundle元数据的目的在于准确描述模块化相关的bundle特征,这样才能让OSGi框架恰当的对bundle进行各种处理工作(比如依赖解析,强制封装等),这些元数据主要有这三个部分:
- 可读的信息(可选):帮助更好地理解和使用bundle
- bundle的标识符(必须):唯一的标识一个bundle
- 代码可见性(必须):定义内部与外部代码
3.2.1 可读的信息
这些内容可以帮助人们直观的了解这个bundle是做什么的,从哪里来。OSGi标准定义了几个元数据条目来达到这个目的,但是所有的条目都不是必须的,并且也不对模块化特性产生任何的影响,OSGi框架会完全无视这些内容。
下面就是一个这类信息的例子:
Bundle-Name: SERC HelloworldBundle-Vendor: GR, SERC
Bundle-DocURL: http://elevenframework.orgBundle-Category: example
Bundle-Copyright: SERC
3.2.2 bundle的标识符
在上个小节提到的可读信息中,有些似乎也能用来唯一标识一个bundle,比如Bundle-Name,但是事实上,他并没有被用来标识一个bundle。早期的OSGi标准中并没有提供标识一个已知bundle的方法,直到OSGi R4标准“唯一bundle标识符”这个东西才被提出来。为了向后兼容,Bundle-Name就不能用来作为标识符了,否则就会增加维护向后兼容的工作,所以新的manifest属性就诞生了:Bundle-SymbolicName
Bundle-SymbolicName: org.serc.helloworld
两者相比,Bundle-Name是给用户读的,而Bundle-SymbolicName是给OSGi框架读的,让OSGi框架能够唯一标识一个bundle。
只用一个Bundle-SymbolicName肯定是可以唯一标识一个bundle了,但是随着时间的推移,你的bundle可能会有新版本,这时候加入版本属性会让你的bundle的信息更加准确。
Bundle-Name: SERC HelloworldBundle-Vendor: GR, SERC
Bundle-DocURL: http://elevenframework.orgBundle-Category: example
Bundle-Copyright: SERC
3.2.3 代码可见性
在JavaSE中的jar包如果放在了classpath里面,那么它对这个classpath下的所有程序都是可见的,并且这种可见性不能改变,而OSGi标准定义了如下的属性用于描述代码的可见性:
-
Bundle-ClassPath—它定义了形成这个bundle的所有代码所在的位置,和Java的classath的概念相近,不同点在于,Java中的classpath是定义的jar包的位置,而这个属性描述的是bundle内部的类在bundle中的路径。有例子如下:
Bundle-ClassPath:.,other-classes/,embedded.jar
-
Export-Package—显式暴露需要和其他bundle共享的代码,每个包之间用逗号分隔,每个包可用修饰词来修饰包的其他特征。
Export-Package: org.serc.hellworld; vendor=”SERC”, org.serc.hellworld.impl; vendor=”GouRui”
-
Import-Package—定义该bundle所依赖的外部代码,其格式和Export-Package相同,并且也可以使用修饰词来修饰包。不过这里的修饰词是用来限制所依赖包的范围的,像是一个过滤器,而不像Export-Package中用来声明包的特征。例如如下语句:
Import-Package: org.serc.helloworld; vendor=”SERC”
4 总结
通过这一章,希望读者们能够对OSGi模块层有一个初步的了解,明白这一层着重解决的是一些什么问题,并且在这之后配合着《OSGi开发环境的建立和HelloWorld》这一章可以尝试着自己创建一个bundle,通过在MANIFEST文件中填写元数据来暴露一些包,引入一些包。在下一篇入门篇中,我们将讲解OSGi的生命周期层。
相关推荐
在日常的开发和使用中,我们经常需要借助各种小工具来提高工作效率,例如快速启动常用的应用程序、管理文件等。一个简单但功能强大的集成工具箱可以帮助用户快速访问、启动并管理程序。今天,我们将以Python为基础,结合Tkinter和Win32API,开发一个类似Windows快捷方式的工具箱应用,能够让你轻松集成各种常用程序并一键启动
django自建博客app
《基于YOLOv8的智慧校园实验室高压灭菌锅安全联锁系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计
用于hifi测序数据的基因组组装程序
Microsoft Access 2010 数据库引擎可再发行程序包AccessDatabaseEngine-X64解压后的文件AceRedist
从大模型、智能体到复杂AI应用系统的构建——以产业大脑为例
自然语言处理之TF-IDF算法与TextRank算法的缠绵_textrank,tf-idf和两者的组合-CSDN博客.html
内容概要:2023版《科学智能 (AI4S)全球发展观察与展望》阐述了AI for Science(AI4S)在全球范围内的最新进展及其对科学和工业的深远影响。文章首先回顾了AI4S在过去一年中的快速发展,特别是在药物研发、材料科学、地质学、污染治理等多个领域的应用实例。AI4S通过结合深度学习、机器学习和其他AI技术,加速了从基础研究到实际应用的转化过程。例如,在药物研发中,AI4S帮助科学家克服了“反摩尔定律”的挑战,提高了新药研发的成功率;在材料科学中,AI4S实现了复杂材料的高效模拟,如人造钻石、石墨烯、碳纳米管等;在地质学中,AI4S通过模拟地球内部结构和物理过程,为地震学研究提供了新视角。此外,文章还探讨了大语言模型(LLMs)与科学方法的结合,指出LLMs不仅能辅助科学研究,还能生成新的科学假设并进行逻辑推理。 适合人群:具备一定科研背景或对AI技术感兴趣的科研人员、工程师、政策制定者及高校师生。
这个数据集包含了日常步数统计、睡眠时长、活跃分钟数以及消耗的卡路里,是个人健康与健身追踪的一部分。 该数据集非常适合用于以下实践: 数据清洗:现实世界中的数据往往包含缺失值、异常值或不一致之处。例如,某些天的步数可能缺失,或者存在不切实际的数值(如10,000小时的睡眠或负数的卡路里消耗)。通过处理这些问题,可以学习如何清理和准备数据进行分析。 探索性分析(发现日常习惯中的模式):可以通过分析找出日常生活中的模式和趋势,比如一周中哪一天人们通常走得最多,或是睡眠时间与活跃程度之间的关系等。 构建可视化图表(步数趋势、睡眠与活动对比图):将数据转换成易于理解的图形形式,有助于更直观地看出数据的趋势和关联。例如,绘制步数随时间变化的趋势图,或是比较睡眠时间和活动量之间的关系图。 数据叙事(将个人风格的追踪转化为可操作的见解):通过讲述故事的方式,把从数据中得到的洞察变成具体的行动建议。例如,根据某人特定时间段内的活动水平和睡眠质量,提供改善健康状况的具体建议。
框架结构天城商业办公楼5200平米(建筑图 结构图 计算书 开题报告 任务书 文献翻.zip
柴油机连杆加工工艺及夹具设计.zip
读书网首页的HTML信息
文字渐变颜色代码生成器:让文字绽放多彩魅力,演示:在信息交流日益丰富的今天,个性化的文字展示成为吸引目光的关键。这款文字渐变颜色代码生成器,便是为满足这一需求而生的绿色软件,无需安装,便捷实用。 它的操作极为简便。用户只需在软件界面中输入想要转换的文字内容,接着从丰富的色彩选项里挑选心仪的起始颜色与结束颜色,随后轻轻按下 “转换按钮”,神奇的事情就此发生 —— 适用于论坛、网页、QQ 空间等多种平台,以及自定义格式的渐变颜色代码便会即刻生成。不仅如此,生成的代码还能自动复制到剪切板,极大地节省了用户手动复制的时间。当你在论坛回帖、更新网页内容或是装扮 QQ 空间时,只需轻松粘贴代码,原本单调的文字瞬间就能拥有绚丽的渐变色彩,瞬间脱颖而出,为你的表达增添独特魅力,让文字不再平凡,轻松成为视觉焦点。 一款可以轻松把一段文字生成渐变颜色代码的绿色软件,当你在软件中输入完要转换的文字后,只需要挑选自己喜欢的起始颜色、结束颜色后,按一下―转换按钮即可生成相应的论坛/网页/QQ空间以及自定义格式代码,并且代码可以自动复制到剪切板中,回帖时直接粘贴代码即可不错得文字代码生成器,让你得文字更加漂亮.
1.【锂电池剩余寿命预测】Transformer锂电池剩余寿命预测(Matlab完整源码和数据) 2.数据集:NASA数据集,已经处理好,B0005电池训练、B0006测试; 3.环境准备:Matlab2023b,可读性强; 4.模型描述:Transformer在各种各样的问题上表现非常出色,现在被广泛使用。 5.领域描述:近年来,随着锂离子电池的能量密度、功率密度逐渐提升,其安全性能与剩余使用寿命预测变得愈发重要。本代码实现了Transformer在该领域的应用。 6.作者介绍:机器学习之心,博客专家认证,机器学习领域创作者,2023博客之星TOP50,主做机器学习和深度学习时序、回归、分类、聚类和降维等程序设计和案例分析,文章底部有博主联系方式。从事Matlab、Python算法仿真工作8年,更多仿真源码、数据集定制私信。
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。
Android项目原生java语言课程设计,包含LW+ppt
配套文章:https://blog.csdn.net/gust2013/article/details/146909670?spm=1001.2014.3001.5502
《基于YOLOv8的智慧社区儿童游乐设施安全监测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计