Springboot Application 集成 OSGI 框架开发

Java 类加载器

启动类加载器 (Bootstrap ClassLoader)

是 Java 类加载层次中最顶层的类加载器,负责加载 JDK 中的核心类库,如:rt.jar、resources.jar、charsets.jar 等

扩展类加载器(Extension ClassLoader)

负责加载 Java 的扩展类库,默认加载 JAVA_HOME/jre/lib/ext/目下的所有 jar

应用类加载器(Application ClassLoader)

负责加载应用程序 classpath 目录下的所有 jar 和 class 文件。

ClassLoader 使用的是双亲委托模型来搜索类的,每个 ClassLoader 实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它 ClassLoader 实例的的父类加载器。当一个 ClassLoader 实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器 Bootstrap ClassLoader 试图加载,如果没加载到,则把任务转交给 Extension ClassLoader 试图加载,如果也没加载到,则转交给 App ClassLoader进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等 URL 中加载该类。如果它们都没有加载到这个类时,则抛出 ClassNotFoundException 异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的 Class 实例对象。

判别两个类是否相同,除了是相同的 class 字节码,还必须由同一类加载器加载。比如类 Example,javac 编译之后生成字节码文件 Example.class,ClassLoaderA 和 ClassLoaderB 这两个类加载器并读取了 Example.class 文件,并分别定义出了 java.lang.Class 实例来表示这个类,对于 JVM 来说,它们是两个不同的实例对象,但它们确实是同一份字节码文件,如果试图将这个 Class 实例生成具体的对象进行转换时,就会抛运行时异常 java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Class

OSGI 类加载器

OSGI 类加载器并不遵循 Java 的双亲委派模型,OSGi 为每个 bundle 提供一个类加载器,该加载器能够加载 bundle 内部的类和资源,bundle 之间的交互是从一个 bundle 类加载器委托到另一个 bundle 类加载器,所有 bundle 都有一个父类加载器。

Fragment bundle 是一种特殊的 bundle,不是独立的 bundle,必须依附于其他 bundle 来使用。通过 Fragment-Host 来指定宿主 bundle,同时也可以通过这种方式使用宿主的类加载器。

图 1.OSGI 类加载器

image

OSGI 框架根据 Bundle 的 MANIFEST.MF 文件中描述的数据信息进行解析处理 Bundle 间的依赖关系。Fragment Bundle 的宿主 bundle 的检查在 bundle 解析之前已经完成,所以 Fragement Bundle 可以获取到宿主 bundle 的加载器信息。

Equinox OSGI ServletBridge 实现原理及源码解析

BridgeServlet 与 OSGI 容器

Equinox 提供了 servletbridge.jar 将 OSGI framework 和 servlet container 桥接起来,并且提供了一系列的 bundle 可以将 Equinox OSGI 应用嵌入到现有的 web 服务器中(eg. Tomcat)。servletbridge.jar 包含如下两个文件 (package: org.eclipse.equinox.servletbridge)

BridgeServlet – 负责请求处理

FrameworkLauncher – 负责 OSGI bundle 启动管理

Web 工程被加载到 web 容器中,比如 Tomcat,容器读取 web 工程 WEB-INF 目录下的 web.xml 文件,通过 servlet mapping 指定相应的类处理请求......

https://www.ibm.com/developerworks/cn/java/j-springboot-application-integrated-osgi-framework-development/index.html

总结

本文从 Java 类加载器说起,探讨了 OSGI 的类加载器原理并对 Equinox 中的 Servletbridge 原理实现进行了详细的研究,同时扩展到使用这一原理如何在 Spring boot 应用中嵌入 OSGI 开发和 Spring boot 应用如何与 OSGI 插件之间进行相互调用。使用一个例子来对这一系列的使用做了进一步的讲解。并对它的实现方法做了进一步的探讨,这些探讨对于将 OSGI 应用嵌入到任何其他的系统中是一个启发和帮助,希望有兴趣的读者可以做进一步的了解和实现。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java 成神之路

深入理解 Synchronized

2829
来自专栏pangguoming

ElasticSearch客户端注解使用介绍

The best elasticsearch highlevel java rest api-----bboss

1083
来自专栏一枝花算不算浪漫

页面静态化技术Freemarker技术的介绍及使用实例.

3976
来自专栏程序员互动联盟

【答疑解惑】如何避免程序崩溃之一

避免程序崩溃,有很多方法,分别针对不同的崩溃原因,我今天想谈谈一种程序员经常碰到的、不管是初学者甚至编程老手都经常犯的错误,就是程序运行时栈的崩溃。 这种错误相...

3658
来自专栏张善友的专栏

自动类型安全的.NET标准REST库refit

在SCOTT HANSELMAN 博客上看到一个好东西《Exploring refit, an automatic type-safe REST library...

1997
来自专栏python3

习题20:函数和文件

readline()函数返回的内容中包含文件本来就有的\n,而print在打印时又会添加一个\n

983
来自专栏Java帮帮-微信公众号-技术文章全总结

Spring scope 作用域

Spring scope 作用域 今天研究了一下scope的作用域。默认是单例模式,即scope="singleton"。 另外scope还有prototype...

3765
来自专栏Golang语言社区

Golang 序列化之 ProtoBuf

ProtoBuf: 是一套完整的 IDL(接口描述语言),出自Google,基于 C++ 进行的实现,开发人员可以根据 ProtoBuf 的语言规范生成多种编程...

3565
来自专栏Android相关

Android---SharedPreferences解析

SharedPreferences真正实现的类是:SharedPreferencesImpl

1793
来自专栏zingpLiu

浅析Python多线程

学习Python多线程的资料很多,吐槽Python多线程的博客也不少。本文主要介绍Python多线程实际应用,且假设读者已经了解多线程的基本概念。如果读者对进程...

2188

扫码关注云+社区

领取腾讯云代金券