karaf内嵌文件服务器,关于OSGI(Karaf) Classloader的几点说明

1. Java ClassLoader

Java通过Classloader加载Class,Classloader之间相互隔离。隔离真正的意思是:不同的Classloader可以加载相同的class定义,并且被jvm认定为不同的class。很多人对隔离有误解,认为不同的Classloader之间不能相互访问,这其实并不准确。可以这么理解:Classloader只是一个普通的Java类,加载的class集合是它的一个成员变量。如果一个Classloader中维护了另一个Classloader的引用,自然可以通过接口调用查找并使用另一个Classloader加载的类,双亲委派使用的正式这种机制。

双亲委派这名字乍一听好像是说你有父亲、母亲两个Classloader,你可以委派他们两个先去加载class,他们处理不了的你再处理。如果真这么理解就全错了。首先,他们不是两个,可能是n个;其次,他们不是你的父母,他们是整个jvm共享的Classloader;第三,他们谁的父母都不是,因为你和他们没有血缘(别人也没有),你不是双亲Classloader的子类。

双亲委派的英文为parent delegation,指的是每个Classloader都有一个getParent方法获取上一级的Classloader。查找类时,先调用parent Classloader查找,如果找不到在用自身的Classloader查找。层级关系如下:

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

parent delegation

双亲委派实际上只是引用关系,上述bootrasp、extension、application Classloader之间关系均属此类。再来看另外一张图:

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

自定义Classloader

bootrasp、extension、application Classloader在jvm中只有一个实例,多个用户自定义的Classloader共享此实例,完成公共部分加载。

2. OSGI Classloader

在OSGI中,每一个Bundle有一个单独的Classloader实例。更具体点,BundleWiringImpl中定义了一个BundleClassLoader,每当加载一个bundle时,框架创建一个BundleClassLoader实例负责该bundle相关class的加载工作。

BundleClassLoader的加载顺序如下:

如class在 java.* package中,委托Bootstrap Classloader处理;

如class定义在 OSGi 框架中启动委托列表(org.osgi.framework.bootdelegation)中,则将加载请求委托给Bootstrap Classloader处理;

如class在 Import-Package 定义的package中,则框架找到导出此package的 Bundle 的 Class Loader,交其处理 。

如class属于在 Require-Bundle 中定义的 Bundle,则框架找到导出此package的Bundle的ClassLoader,交其处理。

Bundle 搜索自己的类资源 ( 包括 Bundle-Classpath 里面定义的类路径和属于 Bundle 的 Fragment 的类资源);

若类在 DynamicImport-Package 中定义,则开始尝试在运行环境中寻找符合条件的 Bundle 。

Bundle之间隔离,但如果存在import关系又可以委托给相应export的classloader处理。实现上无非是维护了多个import bundle的Classloader,查找时调用其find方法实现。

需要注意的是:查找时优先查找Import-Package、Require-Bundle中的类,随后才是查找Bundle自己的类。这里又引入另外一个疑问,Embed-Dependency使用问题。

简单来说,如果一个Bunlde 需要使用protobuf-java.jar,有如下两种使用方式:

普通的dependency方式使用,如下图的Component C的使用方式。

Embed-dependency方式使用,如下图的ComponentA、ComponentB,此时将protobuf-java做为Bundle自身的一部分使用。

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

embed-dependency

按类加载的顺序,如果先加载Import-Package随后加载自身的Class,在外部存在protobuf-java,又有内嵌的protobuf-java时,如何做到使用自己的而非外部的呢?答案是在Embed-dependency中的jar并不会出现在Import-Package中。

最后再来讲一下,为什么每个bundle需要分配单独的Classloader,解决什么问题。在我看来,最主要的原因有如下两个:

定制导出类。非osgi环境下,所有package中的java类都将被导出,无法限定哪些只能jar内使用,哪些是需要export出去的。存在各种误用,耦合使用情况。

多版本控制。非osgi环境下,一个jvm对于一个类只允许存在一个版本。osgi中每个bundle是独立开发演进的,可能出现同时存在多个版本。

3. 参考资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529293.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

声明变量的三种方式

声明变量的三种方式 先声明,再赋值:【常用】 数据类型 变量名; 变量名 值; 例: int b; b 5;声明并赋值:【常用】 数据类型 变量名 值; 例: int a 5;多个类型的变量的声明和赋值:…

常用idea快捷键

常用idea快捷键 常用 CtrlF12,可以显示当前文件的结构 CtrlN,可以快速打开类 CtrlShiftN,可以快速打开文件 AltInsert,可以生成构造器/Getter/Setter等 AltEnter,导入包,自动修正 CtrlAltL,格…

char类型自动转换成int类型

char类型自动转换成int类型 char c1 65;int i1 c11;// 此处int类型范围比char大 “1”默认为int 所以char类型自动提升为int类型System.out.println(i1);//此处结果为66

java局部变量简述

java局部变量简述 特点描述作用范围离当前变量最近的大括号({})以内重名问题重合的作用范围不能重名定义位置方法中if (a>10) {int c 20;System.out.println(c);}else {int c30;System.out.println(c);}此处c的作用范围未重合,此处程序成…

eclipse debug(程序调试)单步执行 简述

eclipse debug(程序调试)单步执行 简述 1.在需要程序停止的地方 双击打一个断点 2.右键以debug模式执行(有个虫子标志的选项) 3.单步执行 观察变量的变化 如图所示: debug常见问题: 1.Variables(变量区…

方法中的参数,形参(形式参数)和实参(实际参数)简述

方法中的参数,形参(形式参数)和实参(实际参数)简述 形参(形式参数):表示在定义的方法的时候书写的参数,形参规定了参数的个数、类型、顺序 形参相当于局部变量的声明&…

微信小程序~如何设置页面的背景色

微信小程序~如何设置页面的背景色 众所周知,微信小程序每个页面由.json,.scss,.ts,.wxml这四个文件组成。 有的小伙伴会发现,需要给页面加背景色的时候,只需在此页面的.scss文件中写个page{background-colo…

return中断方法和Unreachable code(永远达不到的代码)

return中断方法和Unreachable code(永远达不到的代码) 1.下面这段代码因为for循环是个死循环,System.out.println(); 执行不到编辑器会报错Unreachable code(永远达不到的代码) public static void main(String[] ar…

java 中for循环中重复定义的变量 为什么不报错?

java 中for循环中重复定义的变量 为什么不报错&#xff1f; public class Test1 {public static void main(String[] args) {int[] arr {1,2,3,4,5};for (int i 0; i < arr.length; i) {int j 1;}} }此处变量 j 所作用的范围为其所在的大括号&#xff08; { } &#xff…

Java JDK 自带排序(Arrays.sort(数组名))与自行编写的降序

JDK 自带排序&#xff08;Arrays.sort(数组名)&#xff09;与自行编写的降序 jdk 自带的排序 Arrays.sort(数组名) 只能进行升序排列 可以与自己写的降序 配合使用 import java.util.Arrays;public class Test1 {//jdk 自带升序public static void m1(int [] arr1) {Arrays.sor…

javaee 中遇到的jdk自带的异常(Exception)

javaee 中遇到的异常&#xff08;Exception&#xff09; 如果输入了类型不匹配的数据&#xff0c;则会报InputMismathException(输入不匹配异常) 如果访问超过数组范围的下标将会报数组下标越界异常&#xff1a;ArrayIndexOutOfBoundsException ( 数组越界异常) 在多态的向下转…

实例变量和局部变量区别

实例变量和局部变量区别 实例变量局部变量定义位置定义在类中定义在方法中作用范围变量所在的整个类中离变量最近的大括号中默认值有默认值&#xff0c;与数组相同无默认值&#xff0c;必须初始化关于重名可以与局部变量重名&#xff0c;就近原则使用重合的作用范围&#xff0…

java this关键字表示当前对象,可以访问属性、方法、构造方法

this关键字的三种访问方式&#xff1a;属性、方法、构造方法 1.访问属性 为了命名的规范&#xff0c;利用this关键字区分了属性与局部变量 public class Persion {String name;char sex;int age ;String hobby;int height;int weight;public Persion(String name,char sex ,in…

Java 访问权限修饰符简述

访问权限修饰符简述 1.类的访问修饰符 public 最大访问权限&#xff0c;本项目中的任何位置都可以访问 默认不写 &#xff1a;包级别的访问权限&#xff0c;智能在同包中访问 package com.qfedu.test2;//public修饰的类 public class A {public static void main(String[] arg…

java 静态与非静态之间的访问规则简述

java 静态与非静态之间的访问规则简述 1.静态与静态之间直接访问 2.非静态&#xff08;实例级别&#xff09;访问静态直接访问 3.静态访问非静态&#xff08;实例级别&#xff09;&#xff0c;必须先创建对象再访问 package com.qfedu.test7; /*** 静态和非静态访问规则&#x…

java super关键字简述

java super关键字简述 super关键字访问父类属性&#xff0c;访问权限必须是允许的super关键字访问父类属性&#xff0c;访问权限必须是允许的当创建子类对象时&#xff0c;默认调用父类的无参构造方法&#xff0c;除非显式调用父类的有参构造方法&#xff0c;也就是说**子类创建…

java 双等号(==) 与equals方法的使用区别

java 双等号&#xff08;&#xff09; 与equals方法的区别 用于比较基本数据类型时&#xff0c;比较的是值用于比较引用数据类型时&#xff0c;比较的是地址equals方法在Object类中比较的也是地址&#xff0c;因为在低层也是使用进行比较String类调用equals方法比较的内容&…

java中的 31 和左移右移的关系简述

java中的 31 和左移右移的关系简述 任何数乘以31 等于 这个数左移 五位 减去这个数 ​ n * 31 (n << 5) - n “ << ” 左移几位 表示乘以2的几次方 “ >> ” 右移几位 表示除以2的几次方 package com.qfedu.test3; /*** 任何数乘以31 等于 这个数左移 五位 …

c++ char* 改变长度重新赋值_[C/C++] 2 :分析下列代码有什么问题?

题目分析下面代码有什么问题&#xff1f;void test2() { char string[10], str1[10]; int i; for(i0; i<10; i) { str1 a; } strcpy( string, str1 ); } 解答代码无法通过编译。因为数组名str1为 char *const类型的右值类型&#xff0c;根本不能赋值。即使想对数组的第…

Java final 关键字简述

final 关键字简述 final:最终 1.final 修饰类 final 修饰的类不能被继承 /*** final修饰的类 不能被继承* author **/ public final class A { } //不能被继承,此处报错 //class B extends A{ // //}2.final修饰方法 final 修饰的方法不能被重写 /*** final 修饰的方法 不能被…