PlayFramework 如何使代码更改在运行时出现而无需重新启动和重新部署?它在内部使用tomcat吗?如果没有,我是否可以将我的 Spring 应用程序放在它使用的服务器容器之上,并获得运行时更改的好处。
注意:我知道在技术上也可以使用 Tomcat 来做到这一点,但是,根据我的经验,它有很多错误,并且不能一直工作。有时,它甚至需要重新加载整个应用程序上下文(大约 16 秒),这不切实际。
PlayFramework 如何使代码更改在运行时出现而无需重新启动和重新部署?它在内部使用tomcat吗?如果没有,我是否可以将我的 Spring 应用程序放在它使用的服务器容器之上,并获得运行时更改的好处。
注意:我知道在技术上也可以使用 Tomcat 来做到这一点,但是,根据我的经验,它有很多错误,并且不能一直工作。有时,它甚至需要重新加载整个应用程序上下文(大约 16 秒),这不切实际。
正如 Zenklys 指出的那样,Play 的工作原理是检查 java 文件的最后修改日期,并将它们与运行时生成的 .class 文件交叉引用。如果它发现某些东西发生了变化,那么它会在运行时重新编译它们。
在 Play 1.x 中 - 使用 eclipse jdt 编译器 (org.eclipse.jdt.internal.compiler.Compiler) 完成重新编译。如果您想查看 Play 1.x 中的代码,只需查看以下类 - https://github.com/playframework/play/blob/master/framework/src/play/classloading/ApplicationCompiler.java
在 Play 2.x 中,Play 似乎是通过与 SBT 工具互连来实现的。看看这个 - https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/core/system/ApplicationProvider.scala
首先,这仅在开发模式下运行时才成立。在 prod 模式下,不再检测到更改。
据我了解,这是因为应用程序不是从 .class 文件而是从 .java 文件运行的。通过观察这些文件的最后修改日期,Play 可以检测何时重新/编译应用程序。
您正在寻找类似JRebel的东西。
Play! doesn't use Tomcat or any other Servlet container. It runs on top of Netty, so it doesn't really follow the Java EE spec. However, you can assemble the app into war package to be deployed on Jetty/Tomcat/you-name-it-server.
I might be wrong in this, but Play! probably makes use of throwaway classloaders in order to load the new class definitions and this is why its reloading mechanism is better than regular hotswap.
如果您在带有 JBoss 的 Eclipse 中运行,您可以将 JBoss 部署目录指向您的本地项目。只要您不更改注入或方法签名,您就可以更改代码,并且大约 75% 的时间可以识别它们。由于 JBoss 使用 Tomcat 作为 servlet 容器,或许 Tomcat 也可以用同样的方式设置。
Jrebel也是专门为此目的而构建的。