java热加载
来源:互联网 发布:优惠券源码 编辑:程序博客网 时间:2024/05/17 01:14
一晃眼,又是周日了.刚吃完中饭,写篇博客了.
今天就说一说昨天看的java热加载,我们都知道java是从.java文件编译后成为.class文件,再加载到虚拟机中进行运行的....现在的问题是,我们怎么判断一个class文件是否更新了呢?
我们再进行把这个更新后的class文件加载进去呢?
热加载能够节约我们大量的调试时间,避免了因为修改了一个类的一点代码,就全部重启整个项目,像我现在的项目,启动时间就半分钟,旧的等半分钟,也没有别的办法.有了热部署之后就只需要重新加载需改后的java的class文件了.
下面会用代码讲解怎么进行热加载.
1.首先我们先一个借口,实现此接口的类进行热加载
/** * Created by zk on 2017/12/23. * 作用: classload. * 实现这个接口的子类需要动态更新(热加载) */public interface BaseManager { void logic();}
2.写借口的实现类
/** * Created by zk on 2017/12/23. * 作用: classload. * 实现接口,此类需要实现java类的热加载功能 */public class MyManager implements BaseManager { @Override public void logic() { System.out.println("zhaojun i miss you very much.... "); System.out.println("today is 周六了"); }}
3.对要进行热加载的类的信息进行封装,方便后面进行类的信息的判断
/** * Created by zk on 2017/12/23. * 作用: classload. * 封装要加载类的信息 */public class LoadInfo { //自定义的类加载器 private MyClassLoader myClassLoader; //记录要加载的类的时间戳 --加载的时间 private long loadTime; private BaseManager baseManager; public LoadInfo(MyClassLoader myClassLoader, long loadTime) { this.myClassLoader = myClassLoader; this.loadTime = loadTime; } public void setBaseManager(BaseManager baseManager) { this.baseManager = baseManager; } public MyClassLoader getMyClassLoader() { return myClassLoader; } public long getLoadTime() { return loadTime; } public BaseManager getBaseManager() { return baseManager; }}
4.封装自己的classLoad,进行class的重新加载到JVM中去
/** * Created by zk on 2017/12/23. * 作用: classload. * 自定义java类加载器,来实现java的类的热加载 */public class MyClassLoader extends ClassLoader{ //要加载的java类的classpath路径 private String classPath; public MyClassLoader( String classPath) { super(ClassLoader.getSystemClassLoader()); this.classPath = classPath; }
/**
* 重新父类的方法
*/ @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] data=this.loadClassData(name);//返回加载后的Class对象return this.defineClass(name,data,0,data.length); } /** * 加载class文件中的内容 * @param name * @return */ private byte[] loadClassData(String name) { try { name = name.replace(".", "/"); FileInputStream is = new FileInputStream(new File(classPath + name + ".class")); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int b=0; while((b=is.read())!=-1){ bos.write(b); } is.close(); return bos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; }}
5.获取class,对其进行判断,没有加载加重新加载到JVM中去,或者修改了也重新加载
/** * Created by zk on 2017/12/23. * 作用: classload. * 工厂模式,加载manager 的工厂 */public class ManagerFactory { //加载热加载类的加载信息 private static final Map<String,LoadInfo> loadTimeMap=new HashMap<String,LoadInfo>(); //要加载的类的classpath public static final String CLASS_PATH="C:/workspace/idea/thinkinJava/out/production/thinkinJava/classload"; //实现热加载的类的全名称,包名+类名 public static final String MY_MANAGER="classload.MyManager"; /** * 获取manager * @param className * @return */ public static BaseManager getManager(String className){ File loadFile = new File(CLASS_PATH + className.replace(".", "/" + ".class")); long lastModified=loadFile.lastModified(); //不包含className为key的loadinfo信息,证明没有被加载,需要加载这么类到JVM,重新加载, if(loadTimeMap.get(className)==null){ load(className,lastModified); //加载类的时间戳变化了,同样重新加载这个类到JVM }else if(loadTimeMap.get(className).getLoadTime()!=lastModified){ load(className,lastModified); } return loadTimeMap.get(className).getBaseManager(); } public static void load(String className,long lastModified){ MyClassLoader myClassLoader = new MyClassLoader(CLASS_PATH); Class<?> loadClass=null; try { loadClass=myClassLoader.loadClass(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } BaseManager manager=newInstance(loadClass); LoadInfo loadInfo = new LoadInfo(myClassLoader, lastModified); loadInfo.setBaseManager(manager); loadTimeMap.put(className,loadInfo); } /** * 以反射的方式创建baseManager子类对象 * @param loadClass * @return */ private static BaseManager newInstance(Class<?> loadClass) { try { return (BaseManager) loadClass.getConstructor(new Class[]{}).newInstance(new Object[]{}); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; }}
6.后台启动一条线程,一直进行监控.与变化就加载进行
/** * Created by zk on 2017/12/23. * 作用: classload. * 后台启动一条线程,刷新重新加载实现了热加载的类 */public class MsgHandle implements Runnable { @Override public void run() { while (true){ BaseManager manager = ManagerFactory.getManager(ManagerFactory.MY_MANAGER); manager.logic(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }}
7.编写测试类
/** * Created by zk on 2017/12/23. * 作用: classload. * 测试java类的热加载 * * * 注意IDEA不是实时编译的,请在eclipse上debug试验 */public class ClassLoaderTest { public static void main(String[] args) { new Thread(new MsgHandle()).start(); }}
注意使用IDEA需要进行设置.才能看出来效果.下面是设置的链接.注意修改.
http://blog.csdn.net/u013938484/article/details/77541050
使用eclipse直接进行debug,就可以进行热加载了
也不是很复杂.
还有5天就可以回家看昭君了.激动ing.
阅读全文
0 1
- java 热编译,热加载
- java热加载
- java的热部署和热加载
- Java 热加载jar包
- java热加载技术hotswap
- 编译Java类后不重启Tomcat有两种方式:热部署、热加载
- java高分局之类热加载
- java热部署及类加载
- Java之——类热加载
- java中的动态加载和热替换
- Java之——类热加载
- Java类加载之热替换
- 热加载
- java热部署与热加载,以及配置tomcat实现热部署的方式
- 热部署和热加载
- Java Class的热替换 自定义ClassLoader加载.class(java热部署实现 )
- Java Class的热替换 自定义ClassLoader加载.class
- Java Class的热替换 自定义ClassLoader加载.class
- 大数据揭秘:低学历成功逆袭概率多少?结果令人震惊!
- 决策树详解
- python数据类型之初识Set(集合)
- c中指针数组与数组指针的区别
- 老司机,滴~让你赚5-50不等红包的机会,截止到圣诞节结束
- java热加载
- 10.4
- Spark操作MySQL数据库
- HTTP消息头(HTTP headers)-常用的HTTP请求头与响应头
- Codeforces Round #454 (Div. 2, based on Technocup 2018 Elimination Round 4) E
- 微信小程序上传图片+java 后端接收实例
- 为什么人们说Python容易?
- python运行selenium chromedriver提示WebDriverException: 'chromedriver' executable needs to be in PATH.
- [Ubuntu笔记]我的Linux之路--常见问题记录(添加中)