二十、类加载实例

看到一套开源的监控系统的热部署功能,梳理了一下,也就相关知识简单备注如下以备忘。

热部署的过程是调用ProcessorManager类的executeProcessor方法,其中先加载Processor的实例,然后调用此Processor实例的execute方法。

public class ProcessorManager implements BeanFactoryAware{

public void executeProcessor(String processCode,ProcessorContext processorContext) throws Exception{
  Processor processor = processorMap.get(processCode);
  KldProcess kldProcess = kldProcessDAO.selectByProcessCode(processCode);
  //当流程中有组件被重新编译或者组件运行参数有变动,需要重新装载流程
  if (processor == null || kldProcess.getIsNeedReload().intValue() == KldProcess.NEED_RELOAD.intValue()) {
   processor = loadProcess(processCode ,processorContext);
   processorMap.put(processCode, processor);
  }
  processor.execute();
 }
 
 private Processor loadProcess(String processCode,ProcessorContext processorContext) throws Exception{
 。。。。。。

   if(component.getComponentSourceType().intValue() == KldComponent.JAVA_TYPE){
    BaseComponent componentInstance = (BaseComponent) kldHotClassLoader.loadClassFromBinery(
      component.getComponentCode(), component.getComponentClassSource(),
      component.getComponentClassSource().length,component.getClassSourceStatus()).newInstance();
    componentInstance.setBeanFactory(beanFactory);
    componentInstance.setRuntimeParameter(parameter);
    node.setComponent(componentInstance);
    node.setScriptType(component.getComponentSourceType());
   }else{
    node.setScriptType(component.getComponentSourceType());
    node.setScriptSource(component.getComponentSource());
   }
   
   node.setRuntimeParameter(parameter);
   node.setBeanFactory(beanFactory);
   node.setErrorHandler(logPrintErrorHandler);
   node.setNodeId(processNode.getNodeId());
   node.setNodeCode(processNode.getNodeCode());
   
   processor.addNode(processNode.getNodeId(),node);
  }
  
  return processor;
 }

 

 

public class KldHotClassLoader {

 private static ClassLoader cl;
 
 /**
  * @param name
  * @param byteArray
  * @param len
  * @return
  * @throws IOException
  * @throws ClassNotFoundException
  */
 public Class<?> loadClassFromBinery(String componentCode,byte[] byteArray,long len , Long classStatus) throws Exception{
  String classesPath = KldComponentManager.getClassesPath();
  String extClassesPath = classesPath.substring(0, classesPath.lastIndexOf(File.separatorChar))+File.separatorChar+"extClasses";
  
  //初始化,需要生成class文件
  if( KldComponent.CLASS_STATUS_NEED_COMPILE.equals(classStatus) ||  KldComponent.CLASS_STATUS_MATCHED.equals(classStatus)){
   File extClassesDir = new File(extClassesPath);
   if(!extClassesDir.exists())extClassesDir.mkdir();
   File classFile= new File(extClassesPath+File.separatorChar+componentCode+".class");
   if(classFile.exists())classFile.delete();
   OutputStream fos = new FileOutputStream(classFile);
   fos.write(byteArray);
   fos.flush();
   fos.close();
   
   @SuppressWarnings("deprecation")
   URL[] externalURLs = new URL[]{new File(extClassesPath+File.separatorChar).toURL()}; 
   cl = new URLClassLoader(externalURLs,KldHotClassLoader.class.getClassLoader());
   Class<?> clazz = cl.loadClass(componentCode);
   
   return  clazz;
   
  }else if(KldComponent.CLASS_STATUS_OUPUT.equals(classStatus)){
   //先判断class文件是否存在,如果不存在则生成
   File extClassesFile = new File(extClassesPath);
   if(!extClassesFile.exists())extClassesFile.mkdir();
   File classFile= new File(extClassesPath+File.separatorChar+componentCode+".class");
   if(!classFile.exists()){
    classFile.getParentFile().mkdirs();
    OutputStream fos = new FileOutputStream(classFile);
    fos.write(byteArray);
    fos.flush();
    fos.close();
   }
   
   @SuppressWarnings("deprecation")
   URL[] externalURLs = new URL[]{new File(extClassesPath+File.separatorChar).toURL()}; 
   cl = new URLClassLoader(externalURLs,KldHotClassLoader.class.getClassLoader());
   Class<?> clazz = cl.loadClass(componentCode);
   
   return  clazz;
  }else{
   throw new Exception("illegal class status");
  }
  
 }

}

 

主要执行加载的代码其实就两句:

URLClassLoader cl = new URLClassLoader(externalURLs,KldHotClassLoader.class.getClassLoader());
Class<?> clazz = cl.loadClass(componentCode);

URLClassLoader的三个构造函数如下:

URLClassLoader(URL[] urls)
          Constructs a new URLClassLoader for the specified URLs using the default delegation parentClassLoader.
URLClassLoader(URL[] urls,ClassLoader parent)
          Constructs a new URLClassLoader for the given URLs.
URLClassLoader(URL[] urls,ClassLoader parent,URLStreamHandlerFactory factory)
          Constructs a new URLClassLoader for the specified URLs, parent class loader, and URLStreamHandlerFactory.

 

        Java利用ClassLoader将类载入内存,通过委派机制,把装载的任务传递给上级的装载器的,依次类推,直到启动类装载器(没有上级类装载器)。如果启动类装载器能够装载这个类,那么它会首先装载。如果不能,则往下传递。当父类为null时,JVM内置的类(称为:bootstrap class loader)就会充当父类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值