热部署功能设计
约 396 字大约 1 分钟
Hot Deployment:涉及到类的加载和卸载机制,在不重启应用情况下动态替换或更新组件
用文件监控机制(如NIO的WatchService)监控类文件的变更。触发热部署
class FileWatcher {
public static void watchDirectoryPath(Path path) {
//检查路径是否是文件夹
try {
Boolean isFolder = (Boolean) Files.getAttribute
(path, "basic:isDirectory", LinkOption.NOFOLLOW_LINKS);
if (!isFolder) {
throw new IllegalArgumentException("Path: " + path + " is not a folder");
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
System.out.println("Watching path: " + path);
//获得文件系统的WatchService对象
FileSystem fs = path.getFileSystem();
try (WatchService service = fs.newWatchService()) {
// 注册路径到监听服务
// 监听目录内文件的创建、修改、删除事件
path.register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
// 开始无限循环,等待事件发生
WatchKey key = null;
while (true) {
key = service.take(); // 阻塞直到有事件发生
for (WatchEvent<?> watchEvent : key.pollEvents()) {
WatchEvent.Kind<?> kind = watchEvent.kind();
// 获取文件路径
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) watchEvent;
Path fileName = ev.context();
System.out.println(kind.name() + ": " + fileName);
}
// 重置watchKey
boolean valid = key.reset();
// 如果watchKey无效退出循环
if (!valid) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//监控当前目录
Path pathToWatch = Paths.get(".");
watchDirectoryPath(pathToWatch);
}
}
自定义类加载器继承java.lang.ClassLoader,重写findClass()方法,实现类加载
public class HotSwapClassLoader extends ClassLoader {
public HotSwapClassLoader() { super(ClassLoader.getSystemClassLoader());}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 加载指定路径下的类文件字节码
byte[] classBytes = loadClassData(name);
if (classBytes == null) {
throw new ClassNotFoundException(name);
}
// 调用defineClass将字节码转换为Class对象
return defineClass(name, classBytes, 0, classBytes.length);
}
private byte[] loadClassData(String name) {
// 实现从文件系统或其他来源加载类文件的字节码
return null;
}
}