OSGi理论与实战

63 %
38 %
Information about OSGi理论与实战
Technology

Published on October 9, 2009

Author: BlueDavy

Source: slideshare.net

Description

和清华学子交流的一个OSGi PPT。

OSGi理论和实战 BlueDavy http://china.osgiusers.org 09.09.15

目标 学习OSGi规范 R4.1,掌握OSGi核心概念; 学习OSGi R4实现框架的实现机制,以更好的使用这些框架; 学习基于Equinox开发OSGi Based的应用; 扩展Equinox,更好的基于Equinox来开发各类应用; 学习分布式OSGi;

大纲 OSGi介绍 OSGi实现框架 扩展Equinox Equinox高级实战 分布式OSGi

1、OSGi介绍 在OSGi中,模块是什么? 模块之间的类是如何做到隔离的? 怎么访问其他模块中的类? 模块的生命周期是怎么样的? 模块之间怎么交互? OSGi提供了哪些常用的Service?

我期望的模块化、动态化 模块化(Java 7中最重要的Feature) 独立,不受其他模块的影响; 其他模块只能访问该模块对外提供的功能; 模块具备独立的生命周期,例如启动、停止、更新等。 动态化 能动态的增加、更新或删除模块,而对于模块来说不需要做额外的处理; 你期望中的?

OSGi是什么 一个标准,基于此标准实现的框架可轻松的构建模块化、动态化的系统; Dynamic Module System For Java; JSR 232、JSR 291; 众多Java Application Server(Weblogic、Glassfish等)所选择的底层框架;

Bundle Bundle是OSGi中部署的最小单位,因此可以认为Bundle就是模块; Bundle就是一个普通的jar包,只是其在MANIFEST.MF中加入了一些特殊的头信息,例如Bundle-Name;

Bundle类隔离机制 Java ClassLoader机制 类由ClassLoader来实现加载,Java动态化实现的基础; 默认情况下有BootStrapClassLoader(jre/lib、jre/classes)、Extension ClassLoader(jre/lib/ext)以及System ClassLoader(-classpath指定)三个级别的ClassLoader; 应用可自行实现ClassLoader以动态的加载类,或加载相应目录下的类;

Bundle类隔离机制 每个Bundle均为独立的ClassLoader,典型的Bundle的ClassLoader结构如下所示:

Bundle类共享机制 Java经典的Delegation模型 在寻找类时首先从parent classloader中寻找,如找不到才在当前classloader中寻找;

Bundle类共享机制 Bundle类加载过程 java.*委派给parent classloader加载; bootdelegation参数中配置的也委派给parent classloader加载,在parent classloader中未找到也继续下面的步骤; 是否在Import-Package中,在则委派给Export-Package的bundle的classloader; 是否在Require-Bundle中,在则委派给相应的Bundle ClassLoader,未找到则继续下面步骤; 在Bundle-Classpath中寻找,未找到则继续下面的步骤; 在fragments bundle的classpath中寻找,未找到则继续下面的步骤; 是否在Export-Package中,未找到则继续下面的步骤; 是否在DynamicImport-Package中,在则委派给相应的Bundle ClassLoader寻找,不在则抛出ClassNotFound异常。

Bundle类共享机制 因此可以通过在MANIFEST.MF中定义Require-Bundle、Import-Package、Export-Package以及DynamicImport-Package来实现类共享; Import-Package: org.osgiusers.china.demo Export-Package: org.osgiusers.china.demo DynamicImport-Package: org.osgiusers.* 注意:OSGi支持包的版本的定义! Import-Package: org.osgiusers.china.demo;version=“[1.0,2.0)”

Bundle类共享机制 Import-Package寻找机制 比较提供了相应package的Bundle的状态,resolved优先于未resolved的; 如均为resolved的bundle,则比较package的版本,默认package版本为0.0.0,版本高的优先于版本低的; 如版本也一样,则比较bundle id,bundle id小的优先于大的,也就是先安装的bundle优先。

Bundle生命周期 OSGi按照下面的状态转换方式来管理Bundle的生命周期; 可通过OSGi提供的API来主动改变Bundle的生命周期。 BundleContext.installBundle Bundle.start Bundle.update Bundle.stop Bundle.uninstall Bundle生命周期改变时所做的动作将直接影响动态化。 INSTALLED STARTING start RESOLVED ACTIVE stop UNINSTALLED STOPPING

Bundle生命周期 Install Bundle时要做的事情 解析Bundle的MANIFEST.MF信息,判断格式是否符合标准以及是否存在相同的Bundle; 分配新的Bundle ID后; 生成Bundle对象,并放入已安装的Bundles集合中,状态置为INSTALLED。

Bundle生命周期 Resolve Bundle时要做的事情 寻找Bundle中所需依赖的包或Bundle是否存在以及被resolve,包括寻找匹配的import-package、require-bundle等,如寻找到则进入检查,检查完冲突后形成绑定关系,以便加载类时能直接加载; 冲突示例 A Bundle依赖org.osgiusers.china.demo;version=1.0.0,org.osgiusers.china.user;version=2.0.0; B Bundle提供了org.osgiusers.china.demo;version=1.0.0,但同时import了org.osgiusers.china.user;version=1.1.0 如成功,则将Bundle状态置为RESOLVED。

Bundle生命周期 Start Bundle时要做的事情 检查Bundle的状态,如未Resolve,则先Resolve; 寻找MANIFEST.MF中配置的Bundle-Activator,如寻找到,则调用其start方法; 将Bundle状态标识为ACTIVE。

Bundle生命周期 Stop Bundle时要做的事情 卸载当前Bundle对外提供的所有OSGi Service,并释放当前Bundle引用的所有OSGi Service; 调用MANIFEST.MF中对应的Bundle-Activator的类的stop方法; 将Bundle状态置为RESOLVED。

Bundle生命周期 Uninstall Bundle时要做的事情 检查Bundle状态,如状态为ACTIVE,则先STOP; 释放Bundle对其他Bundle的类依赖; 如当前Bundle中有其他Bundle的类依赖,则进行记录,如没有则释放该Bundle的ClassLoader; 将当前Bundle的状态置为UNINSTALLED。

Bundle生命周期 Update Bundle时要做的事情 首先停止当前Bundle; 重新安装并RESOLVE Bundle; 恢复到Bundle更新之前的状态。

Bundle生命周期总结 除了DynamicImport-Package外,其他的Package引用哪个Bundle在Resolve时就已经决定了; 如希望更新Bundle所引用到的类,则必须进行refresh动作; 但refresh动作也只对目前处于unresolve状态的以及之前uninstall时还有其他bundle类依赖的Bundle进行unresolve动作,并重新resolve对他们有依赖的bundle。 从上可见,当Bundle有Start动作时,有可能会造成有Bundle的ClassLoader建立成功,当发生Refresh动作时,有可能会造成某些Bundle Resolve失败,也有可能造成某些Bundle重建ClassLoader。

Bundle交互 Service registry packages packages 直接类访问的方式(不推荐),结合上面之前的Bundle生命周期的介绍,为什么?; Service交互方式 直接通过BundleContext.getServiceReference以及BundleContext.registerService这样的方式(使用不方便,不推荐); Declarative Services方式,类似IoC type 2; OSGi Framework Bundle Bundle JAVA Operating System Hardware

Bundle交互 Declarative Services(简称DS) Service-Oriented Component Model 需要对外提供的功能均定义为接口; 接口的实现定义以XML方式定义为Component; 按接口的方式访问其他Bundle的功能; 以XML方式定义对其他Bundle的功能的访问; Component也是有生命周期的。 OSGi R4.0的重大改进就是这点!

Bundle交互 对外提供服务示例 调用其他Bundle的服务示例

Bundle交互 提供服务关键配置 provide interface,声明对外提供的接口; property,可增加一些服务实现的关键词,以便匹配过滤,例如<property name=“KEY” value=“DB”/> 调用服务关键配置 cardinality 配置调用服务的数量,例如0..1、1..n、0..n; policy 配置引用的服务变化时的策略,主要有static和dynamic这两种; target 配置引用的服务的过滤,例如target=“(KEY=DB)”,这样即使有多个提供了接口的服务,也只会注入配置了KEY=DB的这个;

Bundle交互 DS 1.1的可喜变化 Service-Component后指定的文件可用通配符,例如:Service-Component: OSGi-INF/*.xml 可以配置activate和deactivate方法,并且提供了多种方法签名的支持; bind、unbind方法加了两种签名的支持; void <method-name>(ServiceReference) void <method-name>(<parameter-type>,Map) 增加的这个方法签名至关重要,尤其是对于按服务属性来选择服务的场景而言。

Bundle交互 Component生命周期 如Component有对外提供服务,在没有其他Component需要此服务时,这个Component是不会被激活的,只有当有其他Component需要此服务,且当前Component所需的服务均满足条件时,才会被激活; 如Component没有对外提供服务,那么只要此Component所需依赖的服务均可用,则会被激活。

Bundle交互 Component生命周期 当有Bundle启动时,会触发Declarative services的介入,以将其中的Service-Component对应的配置文件的Component载入; 当有Bundle通过BundleContext直接注册服务时,也将触发Declarative Services,以检查是否有Component可被激活; 当有Bundle STOP时,也会触发DS的介入,以将相关的OSGi Service卸载和释放,并检查相关的Component是否要被销毁; 如何做到引用的服务更新了,但当前Component并不会重新创建实例?

R 4.2将会带来的变化 Launch Framework API 这个API的引入就意味着以后可以以一种统一的方式在程序中启动OSGi Framework了,示例如下: Map p=new HashMap(); p.put(“org.osgi.framework.storage”,System.getProperties(“user.home”)+File.separator+”osgi”); FrameworkFactory factory=Class.forName(factoryClassName).newInstance(); Framework framework=factory.newFramework(p); framework.init(); BundleContext context=framework.getBundleContext(); …//安装Bundles framework.start(); framework.waitForStop();

OSGi提供的服务 Http Service 以便支持简单的通过http访问OSGi应用; 但复杂的场景还是比较难支撑,这主要是由于目前还只有jetty实现的HttpService,再加上它所支持的Servlet版本太低,这也导致了目前OSGi对于Web类型的应用而言支持不足,但可喜的是RFC 66会带来很多变化; Log Service 支持简单的日志记录,直接输出到console,不过可以结合log4j自行实现; EventAdmin Service 基于此可实现事件通知性质的功能; ConfigurationAdmin Service 基于此可实现配置信息的动态管理。

OSGi对模块化、动态化的满足程度 模块化 完全满足。 动态化 能够动态的增加、删除或更新模块,并完成依赖的OSGi Service的引用迁移; 但要自行处理由此带来的模块中对象的状态保持和恢复的问题,因此基于OSGi了,并不就代表应用一定可动态了,要合理的基于Bundle生命周期改变和Component生命周期改变会带来的变化做相应的处理。

2、OSGi实现框架 有哪些实现框架? 它们是如何实现OSGi规范的? 它们是否遵循OSGi标准? 对比而言,谁更有优势?

OSGi实现框架 Equinox Equinox是R 4.0的RI,并且也是Eclipse的核心,可谓是久经考验,Spring-DM也是基于Equinox。 Felix Felix作为后起之秀,表现算得上是非常突出了。 其他 Oscar、Knoperfish已是昨日黄花了;

OSGi实现框架 Equinox Equinox的ClassLoader结构

OSGi实现框架 Equinox中的类加载顺序 根据启动时的bootdelegation属性判断是否需要从parent classloader中加载,具体parent classloader是哪个,则可以通过osgi.parentClassLoader属性来指定,支持的为:app(SystemClassLoader)、ext(Extension ClassLoader)和fwk(Equinox ClassLoader)三种; 调用Equinox的ClassLoaderDelegateHook的preFindClass来加载; 从Import-Package中寻找; 从Require-Bundle中寻找; 尝试从当前Bundle中加载; 尝试从DynamicImport-Package中加载; 调用Equinox的ClassLoaderDelegateHook的postFindClass来加载; 尝试使用Eclipse的buddy机制来加载; 对比规范而言,Equinox除了增加了Hook机制以及buddy机制外,完全遵守OSGi规范。

OSGi实现框架 Equinox Install Bundle 按照提供的Bundle文件加载流,并根据MANIFEST.MF的信息形成Bundle对象,并将Bundle的状态置为INSTALLED; 对外广播Bundle INSTALLED事件。

OSGi实现框架 Equinox Resolve Bundle 如bundle为singleton,则首先检查singletons bundle是否已存在,如存在则resolve失败; 对所依赖的package进行寻找、检查和绑定; 寻找require-bundle、import-package匹配的bundle; 检查这些bundle之间是否有冲突,尽可能的选择没有冲突的bundle; 绑定通过检查的bundle,以便在加载类时可直接去这些bundle中寻找。 将Bundle状态设置为RESOLVED。

OSGi实现框架 Equinox Start Bundle 检查状态是否为RESOLVED,如未resolve则先进行resolve动作,resolve失败则直接抛出异常,成功则继续下面步骤; 调用MANIFEST.MF中配置的bundle-activator对应的类的start方法。 将Bundle状态置为ACTIVE。

OSGi实现框架 Equinox Stop Bundle 注销发布的OSGi服务以及释放对其他OSGi服务的引用; 调用MANIFEST.MF中配置的bundle-activator的类的stop方法; 将Bundle状态置为RESOLVED。

OSGi实现框架 Equinox Uninstall Bundle 如Bundle为Active,先停止Bundle; 检查是否有其他Bundle依赖了当前Bundle的package,如有则先不关闭此bundle的classloader,如没有则关闭; 将Bundle状态置为UNINSTALLED。

OSGi实现框架 Equinox Update Bundle 如状态为ACTIVE,先停止; 创建新的Bundle对象,如有Bundle依赖老版本的Bundle,则暂时将老版本的Bundle放入removalPendings中,如没有,则清除老版本Bundle的所有信息; 恢复新版本的Bundle到更新前的状态。

OSGi实现框架 Refresh 找到所有removalPendings中的bundle,unresolve这些bundle,并重新resolve依赖了这些bundle的bundle; 恢复重新resolve了的bundle的状态。

OSGi实现框架 Equinox DS在这些过程中的处理 Start Bundle时 扫描MANIFEST.MF中对应的Service-Component指定的文件,加载这些文件; 判断其中指定的Component是否符合激活条件,如符合,则激活并调用activate方法,对于提供了OSGi Service的Component,则注册此OSGi Service; Stop Bundle时 不做任何动作; 有服务注册时 寻找当前的Component是否有可激活的,如有则进行激活; 寻找当前已激活的Component中是否有需要此OSGi Service的,如有则调用其bind-method进行注入; 有服务注销时 对于依赖了此OSGi Service的component,调用其unbind-method; 检查是否有Component因此不到激活条件的,则尝试调用Component的deactivate方法并销毁Component的实例。

OSGi实现框架 Felix Felix的ClassLoader结构

OSGi实现框架 Felix中的类加载顺序 判断是否为bootdelegation中配置的package,如交由Felix ClassLoader进行加载; 尝试从Import-Package中加载,如在则交由相应的Bundle ClassLoader去加载,即使加载不到也继续下面的步骤; 尝试从当前Bundle的Classpath中加载; 尝试从DynamicImport-Package中加载; 从上面步骤来看,Felix在Import-Package时这步上未遵循OSGi规范,这有些时候可能会造成一些问题。

OSGi实现框架 Felix Install Bundle 解析Bundle的MANIFEST.MF文件,读取OSGi标准中定义的头信息; 检查Bundle的唯一性,如不唯一则抛出异常; 将Bundle状态置为INSTALLED。

OSGi实现框架 Felix Resolve Bundle 寻找需要依赖的Package或Bundle,并将其中未resolve的Bundle进行resolve,如resolve失败,则将其从潜在的Bundle列表中删除,这步完全遵循OSGi规范; 检查是否有符合条件的Bundle,如没有,则抛出异常,有则继续; 检查这些符合条件的潜在的Bundle,如多个同名称的单态Bundle、版本冲突等问题,如这些问题均不存在,则继续下面的步骤; 完成绑定。

OSGi实现框架 Felix Start Bundle 检查Bundle状态,如未resolve则先resolve; 执行MANIFEST.MF中对应的Bundle-Activator配置的类的start方法,如未配置则跳过此步; 将Bundle状态设置为ACTIVE;

OSGi实现框架 Felix Stop Bundle 执行MANIFEST.MF中对应的Bundle-Activator配置的类的stop方法,如未配置则跳过此步; 注销Bundle对外发布的Service; 释放Bundle引用的Service;

OSGi实现框架 Felix Uninstall Bundle 检查状态,如为ACTIVE,则先停止; 如有其他Bundle引用了当前Bundle的package,则将当前Bundle的RemovalPending设置为true; 将Bundle状态设置为UNINSTALLED; 如未被其他Bundle使用,则对当前Bundle执行refresh动作;

OSGi实现框架 Felix Update Bundle 停止当前的Bundle; 重新读取并解析Bundle流,将Bundle状态置为INSTALLED; 恢复Bundle到更新前的状态。

OSGi实现框架 Felix Refresh 在指定Bundle的情况下,递归找到依赖当前Bundle提供的package的Bundle,作为此次refresh动作需要操作的Bundles;在未指定Bundle的情况下,则将已卸载的且RemovalPending为true的Bundles,以及还未resolve的Bundle作为此次需要操作的Bundles; refresh负责将需要uninstall的Bundle对外export的package彻底关闭,并对需要依赖这些package的bundle执行STOP动作; 对于不需要Uninstall但在refresh动作范畴的bundles恢复为之前的状态。

OSGi实现框架 Felix DS在这些过程中的处理 和Equinox基本一致; 但值得注意的是Felix DS 1.0.8对于policy=dynamic、cardinality=“0..1” | “0..n”这类依赖服务变更时的处理有个bug,会造成在依赖的服务更新后出现需要此服务的Component拿不到服务引用的现象。

OSGi实现框架对比

3、扩展Equinox 如何在外部程序中启动Equinox? 是否可以对Equinox进行扩展? 如可以扩展,应如何做?

扩展Equinox 在外部程序中启动Equinox 示例 // 配置Equinox的启动 FrameworkProperties.setProperty("osgi.noShutdown", "true"); FrameworkProperties.setProperty("eclipse.ignoreApp", "true"); FrameworkProperties.setProperty("osgi.bundles.defaultStartLevel", "4"); FrameworkProperties.setProperty("osgi.bundles", "// 指定需要装载的Bundle的路径"); // 指定需要加载的bundles所在的目录 FrameworkProperties.setProperty("osgi.syspath", "// 例如plugins"); EclipseStarter.run(new String[]{"-configuration","configuration","-console"}, null); // 通过EclipeStarter获取到BundleContext context=EclipseStarter.getSystemBundleContext(); 到了R 4.2后就可以遵循标准的API来启动了

扩展Equinox Equinox中可用的扩展 ClassLoadingHook ClassLoaderDelegateHook ClassLoadingStatsHook AdaptorHook 借助这些扩展可以更好的控制Equinox。

扩展Equinox ClassLoadingHook 可用于拦截Bundle ClassLoader的创建、类的处理、Classpath的处理等; ClassLoaderDelegateHook可用于在某个阶段干预类的加载,例如在类从Import-Package中扫描之前或在DynamicImport-Package扫描之后。

ClassLoaderDelegateHook

可用于在某个阶段干预类的加载,例如在类从Import-Package中扫描之前或在DynamicImport-Package扫描之后。

Add a comment

Related presentations

Presentación que realice en el Evento Nacional de Gobierno Abierto, realizado los ...

In this presentation we will describe our experience developing with a highly dyna...

Presentation to the LITA Forum 7th November 2014 Albuquerque, NM

Un recorrido por los cambios que nos generará el wearabletech en el futuro

Um paralelo entre as novidades & mercado em Wearable Computing e Tecnologias Assis...

Microsoft finally joins the smartwatch and fitness tracker game by introducing the...

Related pages

OSGi理论与实战_图文_百度文库

OSGi理论和实战 目标 ? ? ? ? ? 学习OSGi规范 R4.1,掌握OSGi核心概念; 学习OSGi R4实现框架的实现机制,以更好 的使用 ...
Read more

OSGi理论与实战_文库下载

OSGi理论与实战. OSGi理论与实战_经管营销_专业资料。OSGi 理论与实战 — Presentation Transcript ? ? ? ? ? ? ? ? ? ? ? 1. OSGi 理论 ...
Read more

OSGI理论与实战 - 下载频道 - CSDN.NET

OSGI理论与实战 zqiuker2014-12-25 上传. 学习OSGi R4实现框架 ...
Read more

OSGi理论与实战 - 下载频道 - CSDN.NET

下载频道 > 资源分类 > 开发技术 > Java > OSGi理论与实战 OSGi理论与实战 youngedison2013-12-08 上传. OSGi理论与 ...
Read more

OSGi理论与实战_Java认证资料下载_IT认证资料 ...

资料名:OSGi理论与实战,下载文件格式(zip),下载文件大小(527),资料标签(OSGi),本资料免费下载。
Read more

OSGi入门与实战_文库下载

OSGi理论与实战OSGi...? ? 类由ClassLoader来实现加载,Java动态化实现 ...
Read more

OSGi入门与实战_图文_百度文库

OSGi理论与实战. 77 ...
Read more

淘宝网开放平台资深架构师Bluedavy:OSGI理论 ...

淘宝网开放平台资深架构师Bluedavy:OSGI理论与实战淘宝网开放平台资深架构师Bluedavy OSGI 入门经典 淘宝网开放平台 ...
Read more

IT认证资料下载_计算机考试资料下载_资料 ...

OSGi理论与实战.
Read more