jvm-sandbox 模块加载流程
发表时间 2020-04-28  |  浏览量:  |  分类: jvm-sandbox
  1. DefaultCoreModuleManager类的构造方法最后会执行一次reset方法初始化所有模块

  2. reset内部会通过如下代码加载模块

    new ModuleJarLoader(moduleLibDir, cfg.getLaunchMode(), sandboxClassLoader)
            .load(new InnerModuleJarLoadCallback(), new InnerModuleLoadCallback());
    
  3. ModuleJarLoader会扫描模块目录下的所有jar包,然后对每一个jar包都执行从步骤4开始的流程

  4. 先调用ModuleJarLoadCallback.onLoad(moduleJarFile),只有通过了整个模块jar加载链的回调的jar包才能被加载。如果回调链中任何一个回调抛出异常,都不会继续加载该模块(但不影响下一个模块的加载)。

  5. 为该jar包构建一个专用的ModuleClassLoader

  1. 通过Java SPI查找该jar包内配置的Module实现类,通过指定SPI接口的类加载器为ModuleClassLoader实现资源隔离。

  2. Module实现类做合法性校验(Information注解、配置id、符合期望的运行mode)

  3. 调用ModuleJarLoader.ModuleLoadCallback.onLoad(...)加载模块:

    1. 构造对应的模块业务对象CoreModule

    2. 调用injectRequiredResource为模块业务对象注入需要的资源

    3. 调用fireModuleLifecycle发布模块业务对象的LOAD事件
    4. 设置模块业务对象的loaded为true
    5. 根据模块对象的@Information注解,决定是否在加载后激活该模块,如果是,则调用active方法激活该模块
      1. 调用fireModuleLifecycle发布模块业务对象的 ACTIVE事件
      2. 调用coreModule.getSandboxClassFileTransformers()获取所有监听器,并激活其中类型为SandboxClassFileTransformer的监听器。激活方法是调用EventListenerHandlers.getSingleton().active(...)
      3. 设置模块业务对象的activated为true
    6. 将该模块添加到loadedModuleBOMap
    7. 调用fireModuleLifecycle发布模块业务对象的 LOAD_COMPLETED事件
  4. 如果步骤5~8抛出异常 或者 未能成功加载至少一个模块,则调用ModuleJarLoader.closeIfPossible尝试关闭该模块类加载器,因为该模块类加载器实际上没用了,没有模块被加载使用。

关闭