http://mingj.iteye.com/blog/307238
play! 最大的卖点就在于 hot swap,正如它自己宣称的:
reach your maximum productivity。play! 允许开发人员修改java文件,保存,然后刷新浏览器,立马可以看到效果。不需要编译,也不需要重启服务器。
Java 要想实现动态更新 class 文件,不外乎两种手段:替换 classloader、替换 JVM。因为替换 JVM 引起的开销更大,需要维护 JVM 的堆、栈等运行信息,所以 hot swap 通常是选择替换 classloader。比如 grails 里面就是选择替换 classloader,它会自己维护一个线程,定期轮询源文件是否发生修改,以替换原来的 classloader。那么 play! 宣称的 hot swap 又是怎么实现的呢?
让我们来看看play! 的内部流程:
1. play! 使用了 Apache Mina 作为底层的 http server,然后使用了自己关于 Mina IoHandler 接口的实现—— HttpHandler
2. 当浏览器发起一个 request:
2.1 Mina Server 生成一个 Mina Request,转发给 HttpHandler 的 messageReceived 方法
2.2 play! 解析 Mina Request 和 Mina Session,包装成自己的 Request 对象
- Request request = parseRequest(minaRequest, session);
2.3 play! 检测 Route 文件修改情况,根据 Route 配置信息将 Route/Action 的信息赋给 Request 对象
- Router.detectChanges();
- Router.route(request);
2.4 play! 根据当前配置的开发模式来采用不同的策略调用 Action 来理 Request
- if (Play.mode == Play.Mode.DEV) {
- Invoker.invokeInThread(new MinaInvocation(session, minaRequest, minaResponse, request, response));
- } else {
- Invoker.invoke(new MinaInvocation(session, minaRequest, minaResponse, request, response));
- }
2.5 如果 play! 当前是 DEV 模式,invokeInThread方法会让 invocation 对象代理 run() 方法
- public void run() {
- try {
- before();
- execute();
- after();
- } catch (Throwable e) {
- onException(e);
- } finally {
- _finally();
- }
- }
咱们来看看 before() 方法:
- public static void before() {
- Thread.currentThread().setContextClassLoader(Play.classloader);
- if(!Play.id.equals("test")) {
- Play.detectChanges();
- if (!Play.started) {
- Play.start();
- }
- }
-
- }
在 Play 类的 detectChanges() 方法里面,有这么一句:
- classloader.detectChanges();
哈哈,play! 修改源文件后,刷新浏览器即见效的奥秘就在这里了。再进去看看 play! 自定义 classloader 的 detectChanges() 方法:
- public void detectChanges() {
-
- List<ApplicationClass> modifieds = new ArrayList<ApplicationClass>();
- for (ApplicationClass applicationClass : Play.classes.all()) {
- if (applicationClass.timestamp < applicationClass.javaFile.lastModified()) {
- applicationClass.refresh();
- modifieds.add(applicationClass);
- }
- }
- List<ClassDefinition> newDefinitions = new ArrayList<ClassDefinition>();
- Map<Class, Integer> annotationsHashes = new HashMap<Class, Integer>();
- for (ApplicationClass applicationClass : modifieds) {
- annotationsHashes.put(applicationClass.javaClass, computeAnnotationsHash(applicationClass.javaClass));
- if (applicationClass.compile() == null) {
- Play.classes.classes.remove(applicationClass.name);
- } else {
- applicationClass.enhance();
- BytecodeCache.cacheBytecode(applicationClass.enhancedByteCode, applicationClass.name, applicationClass.javaSource);
- newDefinitions.add(new ClassDefinition(applicationClass.javaClass, applicationClass.enhancedByteCode));
- }
- }
- try {
- HotswapAgent.reload(newDefinitions.toArray(new ClassDefinition[newDefinitions.size()]));
- } catch (ClassNotFoundException e) {
- throw new UnexpectedException(e);
- } catch (UnmodifiableClassException e) {
- throw new UnexpectedException(e);
- }
-
- for (Class clazz : annotationsHashes.keySet()) {
- if (annotationsHashes.get(clazz) != computeAnnotationsHash(clazz)) {
- throw new RuntimeException("Annotations change !");
- }
- }
-
- int hash = computePathHash();
- if (hash != this.pathHash) {
-
- for (ApplicationClass applicationClass : Play.classes.all()) {
- if (!applicationClass.javaFile.exists()) {
- Play.classes.classes.remove(applicationClass.name);
- }
- if(applicationClass.name.contains("$")) {
- Play.classes.classes.remove(applicationClass.name);
- }
- }
- throw new RuntimeException("Path has changed");
- }
- }
HotswapAgent类的 reload 方法如下:
- public static void reload(ClassDefinition definitions) throws UnmodifiableClassException, ClassNotFoundException {
- instrumentation.redefineClasses(definitions);
- }
读到这里,也就弄清楚了 play! 怎么实现 hot swap 的原理了,还是调用java.lang.instrument目录下的类和方法来实现的 hot swap。不存在魔法,play! 还是选择了替换 classloader,只不过这个替换动作发生在处理 http request 的时候,于是开发人员用起来就是“刷新浏览器就可以看见效果了”。
分享到:
相关推荐
Java热替换(HotSwap)是一项强大的技术,它允许开发者在JVM运行时更新类的代码,而无需重启应用。这极大地提高了开发效率,因为在调试和修复bug的过程中,我们不再需要频繁地停止、编译和重启应用程序。Java Hot...
hotswap-agent-1.3.1-SNAPSHOT.jar+DCEVM-full-7u79-installer.jar 适用jdk版本1.7.0_79 DCEVM-full-7u79-installer.jar需要在所在目录用java -jar命令运行,jvm运行只指定加载了DCEVM的jdk,运行时jvm设置参数 ...
《Java类热更新技术——Hotswap安装与使用详解》 Hotswap技术,作为一种高效便捷的Java开发工具,允许开发者在不重启服务器的情况下修改并实时应用Java类的更改,极大地提升了开发效率,尤其是在Jboss等应用服务器...
HotSwap正式版是占用内存很小且使用范围很广泛的硬盘热插拔软件,HotSwap最新版可智能识别系统的热插拔设备,在系统中增加一个图标,方便关闭SATA硬盘,这样你的热插拔设备就会比较安全了
在IT行业中,前端开发是构建Web应用程序不可或缺的一部分。...同时,参与开源项目,如研究"node-hotswap-master"的源码,也能帮助开发者深入理解Node.js的模块系统和事件驱动特性,提升自身的编程技能。
**PMBus™ 应用配置文件对于热插拔控制器** (Hot Swap Controller, HSC) 的V1.0版本文档详细规定了热插拔控制器在服务器节点中的应用规范,这些节点接受直流输入电源。该标准旨在通过现有的PMBus命令来支持对节点内...
**CPCI Hotswap 技术详解** CPCI(CompactPCI,紧凑型PCI)是一种基于PCI总线技术的工业级标准,旨在提供更坚固、可靠的计算平台,尤其适用于电信、军事和航空航天等领域。CPCI规范继承了PCI接口的高速数据传输能力...
默认的时候会在HotSwapManager的static模块启动时创建一个hotswap文件夹, hotswap文件夹中有三个文件 1、classes文件夹,就是把java文件编译出来的class文件存放位置 2、java文件夹,就是你要热更的java文件存放...
标题 "4.hotswap.7z" 提到的关键词是 "hotswap",这通常与Java开发中的热替换(HotSwap)技术有关。热替换是指在应用程序运行时,能够替换或更新类的定义,而无需重启应用。这对于开发环境非常有用,因为它提高了...
# 基于Java的Hotswap插件 [![Version](https://img.shields.io/jetbrains/plugin/v/PLUGIN_ID.svg)](https://plugins.jetbrains.com/plugin/PLUGIN_ID) [![Downloads]...
HotSwap,是一款专业的sata硬盘热插拔工具。 大家都知道SATA因盘和ESATA硬盘都可以实现热插拔,可是又不像USB设备一样在系统托盘区有一个关闭图标,如果不关闭就拔下的话,可能造成硬盘数据不完整,严重的还会损坏...
"Play源代码分析1—Server启动过程"和"Play Framework介绍3--使用Eclipse开发和调试"这两篇文档分别对Play框架的启动过程和在Eclipse环境下的开发调试进行了详细解析,对于理解框架内部机制和优化开发环境十分有...
npm install hotswap-module --global CLI用法 以下三个命令均运行script.js文件,并将对require('stream')任何调用替换为require('readable-stream') 。 如果未安装hotswap-module ,只需使用npx运行它: npx hot...
添加hotswap和hotswap-runtime依赖于你的Cargo.toml 。 将具有相同项目名称和路径的dylib构建添加到Cargo.toml 。 添加#![feature(plugin, const_fn)]功能门。 导入插件#![plugin(hotswap)] 。 使用#[hotswap]...
本文将深入探讨启动类加载器、扩展类加载器、系统类加载器以及用户自定义类加载器,同时还会涉及到HotSwap技术。 首先,让我们来看看类加载器的层次结构: 1. Bootstrap ClassLoader(启动类加载器):它是JVM启动...
本SWAP经过测试,无任何问题,只要有点点HTML技术即可进行修改,并把它做成属于你自己的SWAP吧!
HotSwap,是一款专业的sata硬盘热插拔工具。大家都知道SATA因盘和ESATA硬盘都可以实现热插拔,可是又不像USB设备一样在系统托盘区有一个关闭图标,如果不关闭就拔下的话,可能造成硬盘数据不完整,严重的还会损坏...
热插拔(Hot Swap)是CPCI系统中的一个重要特性,允许在系统运行时插入或移除模块,无需中断电源或操作系统,极大地提高了系统的可用性和维护性。 **一、PICMG 2.1 R2.0规范** PICMG(Peripheral Component ...
1、需要用到的agent/commons-agent.jar为hotswap打出来的包(HotSwapManager中定义) 2、需要用到lombok插件 3、测试的class为 DemoTestClazz 4、定时检测热更的class为CheckHotwapSchedule 5、热更后...
HotSwap交换了有关2016年大选的所有帖子(从过道的每一侧)与相关的,可操作的政治参与信息,并抛出了GIF幼犬,以作为一种很好的措施。 帖子不会以任何方式删除或删除。 您仍然可以选择查看它们,但是默认情况下它们...