类容器隔离组件源码浅析

2018/01/01 - 工作 Java

一、 PandoraBootstrap.run

获取当前AppClassLoader的urls(JDK系统jar包、本地maven仓库jar包、业务系统classes文件夹)

生成一个ReLaunchURLClassLoader,也称为bizClassLoader(URLClassLoader类型。构造函数传入urls、parent为AppClassLoader)

创建sar包Archive(本质为一个JarFile) <jar:file:/Users/wuhaibin/.m2/repository/com/taobao/pandora/taobao-hsf.sar-container/2017-10-stable/taobao-hsf.sar-container-2017-10-stable.jar!/com/taobao/pandora/guide.properties>

从sar包中发现的所有的 plugin archive 与 module 名字的对应(暂时没用)

从bizClassLoader里查找所有的plugin jar,并获取它们的url(每个中间件一个,详情搜索com/taobao/pandora/plugin.guide.properties)

从sar包中获取pandora容器相关的包(pandora.container-2.1.7.1.jar等等)

用普通的UrlClassLoader(构造函数传入pandora容器包urls)作为classloader获取PandoraContainer字节码并反射生成实例(构造函数传入sar包url、plugin url、bizClassLoader)。并调用start。

反射调用PandoraContainer实例的getExportedClasses方法,导出class缓存给bizClassLoader。

创建新线程,设置setContextClassLoader为bizClassLoader。启动线程,重新调用应用的main方法。主线程等待新线程停止。

二、 PandoraContainer 类初始化

  1. PipelineContext :保存sar的url、plugin url
  2. ClassLoaderHolder :保存bizClassLoader
  3. ServiceContainer :IOC容器(picocontainer),创建并设置类依赖(DeployService、PluginModuleFactory、ClassLoaderService、SharedClassService、HostInfoService、Pipeline、Context、PandoraServiceManager、InitializerChecker、ClassExporter、LifecycleService、RegistryService)

三、 PandoraContainer 调用start方法

  1. ServiceContainer 初始化并注入类依赖关系
  2. Pipeline 初始化 :根据 pipeline.properties 组装任务链表
  3. 调用 Pipeline 的 execute 方法。按顺序执行pipeline下的类的stepIn和stepOut方法。
## From top to bottom out
## ======================== DEPLOYING ======================== ##
Log4jDefaultInitOverride=com.taobao.pandora.stage.Log4jDefaultInitOverride
MergeFolderPlugin=com.taobao.pandora.stage.MergeFolderPlugin 
DeployPluginModule=com.taobao.pandora.stage.DeployPluginModule 
InitializerCheck=com.taobao.pandora.stage.InitializerCheck
ExportClass2Cache=com.taobao.pandora.stage.ExportClass2Cache
RegisterPandoraService=com.taobao.pandora.stage.RegisterPandoraService
RegisterLifecycleListener=com.taobao.pandora.stage.RegisterLifecycleListener
## ======================== DEPLOYED ======================== ##
ChangeStateDeployed=com.taobao.pandora.stage.ChangeStateDeployed
StartPandoraService=com.taobao.pandora.stage.StartPandoraService

MergeFolderPlugin

合并Plugin,并存储到PipelineContext中。(com.taobao.pandora.plugins.ext_path > pluginUrls > sar包里plugins)

DeployPluginModule

通过DeployService发布所有Plugin模块 。

给定一个模块目录,根据目录中配置文件生成 ModuleClassLoader ,构建PluginModule。

  • priority.properties
  • version.properties
  • import.properties
  • export.properties
  • initializer.properties
  • service.properties
  • listener.properties

InitializerCheck

调用每个module的initializer的permitStartup方法

ExportClass2Cache

用module各自的ModuleClassLoader导出ExportInfo的jarList、packageList、classesList的class到sharedClassService中。

RegisterPandoraService

每个module新建一个PandoraServiceWrapper并调用init方法(service.properties)

RegisterLifecycleListener

每个module注册pluginListeners(listener.properties)。目前没中间件会配置。

ChangeStateDeployed

每个module的状态更改为DEPLOYED

StartPandoraService

每个module新建一个PandoraServiceWrapper并调用start方法。

ModuleClassLoader的加载过程

  1. 已经加载的类
  2. 加载JDK相关的类
  3. com.taobao.pandora开头的选择从PandoraClassLoader中加载
  4. 从共享缓存加载
  5. 根据import语义从bizClassLoader中加载
  6. 从当前classpath下加载
  7. 从bizClassLoader中加载
  8. 从SystemClassLoader下加载

类结构图

参考资料

http://blog.csdn.net/b2222505/article/details/78806252 https://bingoex.github.io/2015/09/17/jvm-book-3-classloader/


如果文章对您有帮助,欢迎扫描下方二维码赞助(一分也是爱噢),谢谢

Search

    一分也是爱噢 一分也是爱

    目录