我来自Tomcat背景,它有一个称为“热代码替换”的好功能 - 它可以替代正在运行的Web应用程序中的Java代码,而不会干扰现有的HTTP会话/初始化对象。
最近我开始学习Play框架,虽然它确实做了“代码替换”,但似乎重启整个应用程序,而不仅仅是替换已更改的代码,因此所有Java对象/静态变量/ HTTP会话迷路了。
是否可以在Play中使用Tomcat的热代码替换功能(或类似功能)?
答案 0 :(得分:0)
如评论中所述,Play被设计为无状态,因此不需要这样的功能。使用会话将您的数据存储在客户端上,重新加载代码后肯定可以使用它。 play.mvc.Http.Session
/ play.api.mvc.Session
使用通过密钥操纵的Cookie。
如果将数据存储在会话中是不适用的(因为它的大小或因为多个客户端全局使用它),请使用cache。诀窍是让你期望在缓存中的任何东西都可以恢复,以防它因某些原因丢失(比如在你的情况下重启)。
对于存储在缓存中的任何数据,需要在数据丢失的情况下实施再生策略。这种理念是Play背后的基础之一,与Java EE不同,Java EE期望会话在其整个生命周期中保留值。
答案 1 :(得分:0)
我认为关于Play的主要内容(只能代表1.x分支)是无状态的,是为了避免在服务器中以任何形式使用“会话”状态(http session,static变量等等)因为我认为它有助于简化可扩展性,但是你可以在客户端的加密cookie中有“登录”状态(每个http请求都发送到服务器),进行身份验证,我认为这就足够了,如果你想要用户数据,只需再次查询数据库(对于简单的字符串也可以将它们存储在会话中)。
无论如何,如果你想在整个应用程序生命周期中“保留”服务器端的某些全局状态,请使用@OnApplicationStop
来序列化当前状态(静态变量,这里和那里的某个对象)和@OnApplicationStart
要再次加载它,此机制与Play开发模式'代码替换'兼容:)。
这样的事情:
<强> SomeObject.java 强>
package util;
import java.io.Serializable;
public class SomeObject implements Serializable {
public String someAttribute;
}
<强> ClassWithStaticState.java 强>
package util;
public class ClassWithStaticState {
public static SomeObject someStateObject;
}
<强> StatePreserver.java 强>
package util;
@OnApplicationStop
public class StatePreserver extends Job {
@Override
public void doJob() throws Exception {
new ObjectOutputStream(new FileOutputStream("preservedstate.bin")).writeObject(ClassWithStaticState.someStateObject);
}
}
<强> StateLoader.java 强>
package util;
@OnApplicationStart
public class StateLoader extends Job {
@Override
public void doJob() throws Exception {
File file = new File("preservedstate.bin");
SomeObject someObject;
if (file.exists()) {
someObject = (SomeObject) new ObjectInputStream(new FileInputStream(file)).readObject();
} else {
someObject = new SomeObject();
someObject.someAttribute = "hey!"; // attribute can be modified at runtime but will be preserved across Play development modifications
}
ClassWithStaticState.someStateObject = someObject;
}
}
有关这些注释http://www.playframework.com/documentation/1.2.3/jobs
的详细说明,请参阅此处实际上我认为Play不是序列化,而是在这些示例中完全替换序列化play.cache.Cache
。