几天研究了一下Tomcat的ClassLoader,在一年多以前,每改一下Java源码都要启动一下Tomcat,觉得很不爽。后来,
生锅锅教了我一招,其实改Java源码是不用重启Tomcat的(主要是改方法内的代码),这就是所谓的“热部署”。一直对这个
比较好奇,这是怎么实现的呢?
下面就来简单的模拟一下热部署,其实原理是比较简单的,就是对比class文件的修改时间,如果class是被修改过了,那么
就用ClassLoader把新的class文件重新加载到内存中。
ClassLoader的主要代码:
package classloader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.text.MessageFormat; /** * 动态加载class文件 * @author Ken * @since 2013-02-17 * */ public class DynamicClassLoader extends ClassLoader { // 文件最后修改时间 private long lastModified; // 加载class文件的classpath private String classPath; /** * 检测class文件是否被修改 * @param filename * @return */ private boolean isClassModified(String name) { File file = getFile(name); if (file.lastModified() > lastModified) { return true; } return false; } public Class<?> loadClass(String classPath, String name) throws ClassNotFoundException { this.classPath = classPath; if (isClassModified(name)) { return findClass(name); } return null; } /** * 获取class文件的字节码 * @param name 类的全名 * @return */ private byte[] getBytes(String name) { byte[] buffer = null; FileInputStream in = null; try { File file = getFile(name); lastModified = file.lastModified(); in = new FileInputStream(file); buffer = new byte[in.available()]; in.read(buffer); return buffer; } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return buffer; } /** * 获取class文件的真实路径 * @param name * @return */ private File getFile(String name) { String simpleName = ""; String packageName = ""; if (name.indexOf(".") != -1) { simpleName = name.substring(name.lastIndexOf(".") + 1); packageName = name.substring(0, name.lastIndexOf(".")).replaceAll("[.]", "/"); } else { simpleName = name; } File file = new File(MessageFormat.format("{0}/{1}/{2}.class", classPath, packageName, simpleName)); return file; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] byteCode = getBytes(name); return defineClass(null, byteCode, 0, byteCode.length); } }被加载的类:
package test.classloader; public class Hello { public String sayHello(String name) { return "Hello." + name; } }
package classloader; import java.lang.reflect.Method; public class DynamicClassLoaderTest { public static void main(String[] args) throws Exception { while (true) { DynamicClassLoader loader = new DynamicClassLoader(); Class<?> clazz = loader.loadClass("F:\\JavaProjects\\MyTomcat\\bin", "test.classloader.Hello"); Method method = clazz.getMethod("sayHello", String.class); System.out.println(method.invoke(clazz.newInstance(), "Ken")); // 每隔3秒钟重新加载 Thread.sleep(3000); } } }
相关推荐
李白高力士脱靴李白贺知章告别课本剧.pptx
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
C语言项目之超级万年历系统源码,可以做课程设计参考 文章参考:https://www.qqmu.com/4373.html
Jupyter-Notebook
51单片机加减乘除计算器系统设计(proteus8.17,keil5),复制粘贴就可以运行
《中国房地产统计年鉴》面板数据资源-精心整理.zip
Jupyter-Notebook
Jupyter-Notebook
毕业论文答辩ppt,答辩ppt模板,共18套
Jupyter-Notebook
《中国城市统计年鉴》面板数据集(2004-2020年,最新).zip
Python基础 本节课知识点: • set的定义 • Set的解析 • set的操作 • set的函数
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
兵制与官制研究资料最新版.zip
Jupyter-Notebook
七普人口数据+微观数据+可视化+GIS矢量资源-精心整理.zip
Support package for Hovl Studio assets.unitypackage
土壤数据库最新集.zip
Jupyter-Notebook
1991-2020年中国能源统计年鉴-能源消费量(分省)面板数据-已更至最新.zip