Skip to content

实现原理

清英 edited this page Mar 20, 2018 · 4 revisions

模块加载

JarsLink为每个模块创建一个新的URLClassLoader来加载模块,并且为每个模块创建一个单独的IOC容器来存放本模块的BEAN。支持突破双亲委派,申明了overridePackages的包将由子类加载进行加载。

模块的卸载

卸载模块需要满足三个条件

  • 模块里的实例对象没有被引用
  • 模块里的Class没有被引用
  • 类加载器没有被引用

所以需要做到三点卸载实例,卸载类和卸载类加载器,整个模块的卸载顺序如下:

  • 关闭资源:关闭HTTP连接池或线程池。
  • 关闭IOC容器:调用applicationContext.close()方法关闭IOC容器。
  • 移除类加载器:去掉模块的引用。
  • 卸载JVM租户(开发中):卸载该模块使用的JVM租户,释放资源。

模块间隔离

模块化开发需要解决隔离性问题,否则各模块之间会互相影响。

模块之间的隔离有三个层次,类隔离,实例隔离和资源(CPU和内存)隔离。目前JarsLink实现了类隔离和实例隔离,通过为每个模块创建一个类加载器来实现类隔离,通过为模块模块创建一个新的IOC容器来实现实例隔离。资源隔离准备引入JVM多租户来解决。

模块间通讯

模块之间的通讯也有三种方式,RPC,本地调用,深克隆/反射。

  • 本地调用:目前JarsLink的doAction就是使用的这种通讯方式,这种方式要求模块的类加载器是父子关系,且IOC容器也是父子容器。
  • RPC调用:用于跨JVM的模块之间调用。
  • 深克隆/反射(集成中):深克隆其他模块的入参,反射其他模块的方法实现调用。

类加载机制

OSGI类加载机制的关系采用的是网状结构,每个模块通过 Export-Package 来声明我要给别人用哪些类,通过 Import-Package来声明我要用别人的哪些类。而JarsLink采用的是扁平化管理,每个模块都有一个共同的父类,这个父类加载器就是加载ModuleLoader类的加载器。

JarsLink框架类图

JarsLink框架的类图如下:

  • ModuleLoader:模块加载引擎,负责模块加载。
  • ModuleManager:模块管理者,负责在运行时注册,卸载,查找模块和执行Action。
  • Module:模块,一个模块有多个Action。
  • Action:模块里的执行者。