Java热加载

本文介绍了Java热加载的概念,它允许开发者在不重启服务的情况下更新代码。热加载与热部署的区别在于,热部署涉及整个项目的重新部署,而热加载仅重新加载类。文章详细阐述了热加载的实现思路,利用Java的类加载机制避开双亲委派,并通过实例展示了如何进行热加载。此外,还提供了相关阅读材料以深入理解Java热部署和热加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是热加载

热加载是指可以在不重启服务的情况下让更改的代码生效,热加载可以显著的提升开发以及调试的效率,它是基于 Java 的类加载器实现的,但是由于热加载的不安全性,一般不会用于正式的生产环境。

热加载和热部署的区别

首先,不管是热加载还是热部署,都可以在不重启服务的情况下编译/部署项目,都是基于 Java 的类加载器实现的。那么两者到底有什么区别呢?

  • 热部署是在服务器运行时重新部署项目。
  • 热加载是在运行时重新加载 class

热加载实现思路

根据Java的类加载机制,我们可操作的环节只有加载阶段。同时为了避免双亲委派机制的限制,热加载类对系统加载类是不可见的(它加载过了,就变更不了啦),要通过其他加载类加载(如URLClassLoader、自定义加载器等)。

例子

热加载的接口

package com.sky.learn.hotload;

/**
 * 要热加载的类一定要有一个接口或基类引用
 * @author Administrator
 */
public interface HotLoadInf {
	public void show();
}

测试类

package com.sky.learn.hotload;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 测试热加载客户端类
 * 
 * @author Administrator
 *
 */
public class Client {
	private static ClassLoader classLoader;
	private static Class<?> hotLoadClass;

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		HotLoadInf instance= createInstance();
		System.out.println("OPT: show, reload, or exit");
		while (true) {
			// 根据不同的协议命令执行不同的逻辑,利用热加载,我们可以在修改具体的逻辑代码之后不重启服务器实现热加载
			String cmd = br.readLine();
			if (cmd.equalsIgnoreCase("exit")) {
				return;
			} else if (cmd.equalsIgnoreCase("reload")) {
				reloadImpl();
				instance= createInstance();
				System.out.println("HotLoadImpl reloaded.");
			} else if (cmd.equalsIgnoreCase("show")) {
				instance.show();
			}
		}
	}

	/**
	 * 使用加载的类 hotLoadClass 类创建 HotLoadImpl 实例
	 */
	public static synchronized HotLoadInf createInstance() throws Exception {
		if (hotLoadClass == null) {
			reloadImpl();
		}
		HotLoadInf newInstance = (HotLoadInf) hotLoadClass.newInstance();
		return newInstance;
	}

	/**
	 * 用类加载器重新加载 HotLoadImpl
	 */
	public static synchronized void reloadImpl() throws Exception {
		URL[] externalURLs = new URL[] { new URL("file:F://") };
		classLoader = new URLClassLoader(externalURLs);
		hotLoadClass = classLoader.loadClass("com.sky.learn.hotload.HotLoadImpl");
	}
}

创建两个实现类

package com.sky.learn.hotload;

public class HotLoadImpl implements HotLoadInf {
	public void show() {
		System.out.println("I'm HotLoad Test1!");
	}
}
package com.sky.learn.hotload;

public class HotLoadImpl implements HotLoadInf {
	public void show() {
		System.out.println("I'm HotLoad Test2!");
	}
}

将实现类生成的两个.class文件复制到F盘(代码中文件路径)包路径后,删除HotLoadImpl文件。否则会加载应用中该类。

          

执行main方法,reload前修改要加载的class文件名为HotLoadImpl.class。执行结果如下

相关阅读

Java的热部署和热加载

Java服务器热部署的实现原理

深入探索 Java 热部署

Groovy实现代码热载的机制和原理

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值