Grails或Play如何检测更改并热重新加载类?

20
我很好奇,是否有人知道像Grails或Play这样的框架如何检测代码更改并在不重新启动应用程序服务器的情况下自动触发重新编译? Groovy编译器或其动态本质是否有特定的东西可以使这种情况容易发生?
背景是,在我的构建过程中我有一个自定义的代码生成阶段,我希望能够具备类似编辑和刷新的功能。
感谢您提供任何指导,即使我需要查看代码来获取更大的画面也行。
编辑:我应该澄清,我不是要构建Grails插件,而是想了解在servlet容器中的任何应用程序中实现此操作所需的步骤。也就是说,我正在使用Groovy但不是Grails。
编辑2:听起来Play有一个特定的DEV模式,可以启用此热重载功能:http://www.playframework.org/documentation/1.1.1/main#lifecycle 我了解JRebel通过类加载器执行精细的类版本控制,但我假设像Grails或Play这样的Web框架没有达到那个级别。

3
Luke Daley撰写了一篇关于如何使你的Groovy类具有热重载功能的好文章。对你可能很有用:http://ldaley.com/post/653190105/putting-the-artefact-api-to-work-in-your-grails-app - Dana
以下是关于JRebel如何以通用方式实现此功能的一些有趣细节。我假设Grails并不那么复杂!http://www.zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/ - mckamey
我将@Codemwnci的答案标记为解决方案,但如果有人对Grails有深入了解,我仍然很感兴趣。谢谢! - mckamey
1个回答

13

Play使用Eclipse JDT在运行时编译代码。

请看以下类,该类由Play用于在运行时执行必要的编译操作。

https://github.com/playframework/play/blob/master/framework/src/play/classloading/ApplicationCompiler.java

另外,需要注意Play中DEV模式和PROD模式之间的区别。这是Play开发人员作出的设计决策,一旦将应用程序放入生产模式,服务器启动时会编译类,并且不会检查热重载。这是有道理的,因为在PROD模式下,您的代码实际上不应该再更改。

在DEV模式下,每次收到新请求时都会检查Java文件更新,任何更改的文件都会自动重新编译(并直接在浏览器中显示错误)。在DEV模式下,这个过程非常高效,因为您经常会更改代码,并且即时的反馈非常强大。


太棒了。非常有趣。感谢提供链接和见解。 - mckamey
@Codemwnci 这种方式适用于类的任何变化吗?例如方法签名或继承关系? - Saeed Zarinfam
它应该能够识别层次结构中的类已更改,并在幕后相应地重新编译。 - Codemwnci
不,这并不一定更有效率。如果你依赖于任何计算量大且大小较大的缓存,那么相反的情况就是真的,这种类重新加载的方法会彻底破坏你的生产力,因为它也会清除昂贵的缓存,使得每次更改源代码时都需要重新计算。另一种选择是将计算量大的缓存隔离出来,在单独的JVM中运行,但通常所需的重构成本太高而无法实现。 - Coder Guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接