返回顶部
首页 > 资讯 > 精选 >怎么用源码分析Play Framework hotswap
  • 267
分享到

怎么用源码分析Play Framework hotswap

2023-06-17 11:06:21 267人浏览 八月长安
摘要

这期内容当中小编将会给大家带来有关怎么用源码分析Play Framework hotswap,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Play Framework hotswap的卖点就在于 hot

这期内容当中小编将会给大家带来有关怎么用源码分析Play Framework hotswap,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

Play Framework hotswap的卖点就在于 hot swap,正如它自己宣称的:

reach your maximum productivity。play! 允许开发人员修改java文件,保存,然后刷新浏览器,立马可以看到效果。不需要编译,也不需要重启服务器

Java 要想实现动态更新 class 文件,不外乎两种手段:替换 classloader、替换 JVM。因为替换 JVM 引起的开销更大,需要维护 JVM 的堆、栈等运行信息,所以 hot swap 通常是选择替换 classloader。比如 grails 里面就是选择替换 classloader,它会自己维护一个线程,定期轮询源文件是否发生修改,以替换原来的 classloader。那么 play! 宣称的 hot swap 又是怎么实现的呢?

让我们来看看play! 的内部流程:

play! 使用了 Apache Mina 作为底层的 Http server,然后使用了自己关于 Mina ioHandler 接口的实现—— HttpHandler

当浏览器发起一个 request:

1 Mina Server 生成一个 Mina Request,转发给 HttpHandler 的 messageReceived 方法

2 play! 解析 Mina Request 和 Mina Session,包装成自己的 Request 对象

Request request = parseRequest(minaRequest, session);

3 play! 检测 Route 文件修改情况,根据 Route 配置信息将 Route/Action 的信息赋给 Request 对象

Router.detectChanges();  Router.route(request);

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));  }

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() {  // Now check for file modification  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);  }  // Check new annotations  for (Class clazz : annotationsHashes.keySet()) {  if (annotationsHashes.get(clazz) != computeAnnotationsHash(clazz)) {  throw new RuntimeException("Annotations change !");  }  }  // Now check if there is new classes or removed classes  int hash = computePathHash();  if (hash != this.pathHash) {  // Remove class for deleted files !!  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 的时候,于是开发人员用起来就是“刷新浏览器就可以看见效果了”。

上述就是小编为大家分享的怎么用源码分析Play Framework hotswap了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网精选频道。

--结束END--

本文标题: 怎么用源码分析Play Framework hotswap

本文链接: https://lsjlt.com/news/288531.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么用源码分析Play Framework hotswap
    这期内容当中小编将会给大家带来有关怎么用源码分析Play Framework hotswap,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Play Framework hotswap的卖点就在于 hot ...
    99+
    2023-06-17
  • Play Framework怎么用
    本篇内容介绍了“Play Framework怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!准备安装 Java 5 以上版本及Play。...
    99+
    2023-06-17
  • 如何用Play源代码分析Server启动过程
    这期内容当中小编将会给大家带来有关如何用Play源代码分析Server启动过程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Play是个Rails风格的Java Web框架。如何调试请看此处。以下进入正题...
    99+
    2023-06-17
  • 怎么用源代码分析FileZilla
    本篇文章给大家分享的是有关怎么用源代码分析FileZilla,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。FileZilla是一种快速、可信赖的FTP客户端以及服务器端开放源代...
    99+
    2023-06-16
  • HashMap源码怎么分析
    这篇文章主要介绍“HashMap源码怎么分析”,在日常操作中,相信很多人在HashMap源码怎么分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”HashMap源码怎么分析”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-05
  • 怎么进行ActionInvoker源码分析
    本篇内容介绍了“怎么进行ActionInvoker源码分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!throw new&nbs...
    99+
    2023-06-17
  • vue使用源码分析
    本篇内容主要讲解“vue使用源码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue使用源码分析”吧!生命周期0版本1.哪些生命周期接口initCreatedbeforeCompileCom...
    99+
    2023-07-04
  • Retrofit源码分析&实践(一)【从使用入手分析源码】
    Retrofit源码分析&实践系列文章目录 Retrofit源码分析&实践(一)【从使用入手分析源码】 Retrofit源码分析&实践(二)【Retrofit 免费的api测试工具引入】 Retro...
    99+
    2023-09-16
    retrofit okhttp android
  • 怎么用Hadoop源码分析心跳机制
    这篇文章将为大家详细讲解有关怎么用Hadoop源码分析心跳机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一.心跳机制 hadoop集群是master/slave模式,master包括Na...
    99+
    2023-06-17
  • 怎么进行FileZilla源代码分析
    怎么进行FileZilla源代码分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。FileZilla是一种快速、可信赖的FTP客户端以及服务器端开放源代码程式,具有多种特色...
    99+
    2023-06-16
  • Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
    Spring中的数据访问,JdbcTemplate使用及源码分析 前言 本系列文章为事务专栏分析文章,整个事务分析专题将按下面这张图完成 对源码分析前,我希望先介绍一下Spring中数据访问的相关内容,然后层层递进到事物的源码分析,主要分...
    99+
    2019-10-22
    Spring事务源码分析专题(一)JdbcTemplate使用及源码分析 数据库入门 数据库基础教程 数据库 mysql
  • laravel源码分析队列Queue方法怎么用
    本篇内容介绍了“laravel源码分析队列Queue方法怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!队列任务的创建先通过命令创建一个...
    99+
    2023-06-29
  • Java HashMap使用源码分析
    这篇文章主要讲解了“Java HashMap使用源码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java HashMap使用源码分析”吧!0. 成员变量首先我们先看...
    99+
    2023-07-06
  • Netty源码分析NioEventLoop怎么执行select
    本篇内容主要讲解“Netty源码分析NioEventLoop怎么执行select”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Netty源码分析NioEventLoop怎么执行select”吧!...
    99+
    2023-06-29
  • 怎么用java源代码分析jvm.dll装载过程
    怎么用java源代码分析jvm.dll装载过程,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。简述众所周知java.exe是java class文件的执行程序,但...
    99+
    2023-06-03
  • 如何用源代码分析FileZilla
    这期内容当中小编将会给大家带来有关如何用源代码分析FileZilla,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。FileZilla是一种快速、可信赖的FTP客户端以及服务器端开放源代码程式,具有多种特色...
    99+
    2023-06-16
  • 源码分析Android LayoutInflater的使用
    LayoutInflater 开头先附一段LayoutInflater类的注释简介 这是LayoutInflater开头的一段介绍,我们能看到几个重要的信息: LayoutInf...
    99+
    2023-05-16
    Android LayoutInflater使用 Android LayoutInflater源码 Android LayoutInflater
  • 源码分析Android rinflate的使用
    目录rinflate源码解析递归类型判断TAG_REQUEST_FOCUSTAG_TAGTAG_MERGETAG_INCLUDEparseInclude第一部分:查找layout属性...
    99+
    2023-05-16
    Android rinflate使用 Android rinflate源码 Android rinflate
  • AndroidWorkManager使用以及源码分析
    目录1、前言2、使用2.1、引用2.2 使用2.3 重要概念3、原理3.1 约束检测3.2 任务调度器3.3、任务流程4、总结1、前言 WorkManager 是适合用于持...
    99+
    2023-02-13
    Android WorkManager使用 Android WorkManager
  • Golang中Slice使用源码分析
    本文小编为大家详细介绍“Golang中Slice使用源码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang中Slice使用源码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、slice结构体首...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作