我正在使用以下代码来测试 ConversationScoped 的操作,但我不明白它是如何工作的。我打开对话,设置conversationBean.i的值= 1,然后关闭对话并打开一个新对话,但conversationBean.i的值仍然是1,为什么?它应该是空的,不是吗?
@WebServlet(value = "/tes")
public class MyTag extends HttpServlet {
@Inject
ConversationBean conversationBean;
@Override
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) {
conversationBean.startConversation();
conversationBean.doSomething();
conversationBean.out();
conversationBean.endConversation();
conversationBean.startConversation();
conversationBean.out();
}
}
@ConversationScoped
class ConversationBean implements Serializable {
int i = 0;
@Inject
private Conversation conversation;
public void startConversation() {
conversation.begin();
}
public void doSomething() {
i++;
}
public void out() {
System.out.println(i);
}
public void endConversation() {
conversation.end();
}
}
告诉我,也许我听错了?如果是这样,您能否提供一个简单的示例,它确实表明关闭对话时,与其关联的所有资源都被清除?
@ConversationScoped
主要与 JSF 相关,在该上下文中“对话”一词具有特殊含义。我还没有真正使用过它,但我希望它有时对于 JSF 组件的支持 bean 是有意义的。
Conversation
对象提供了一种访问 JSF 对话的某些属性的方法。
我打开对话,设置conversationBean.i的值=1,然后关闭对话并打开一个新对话,但conversationBean.i的值仍然是1,为什么?
注入的
ConversationBean
实例可能会因请求而异,但通过对 servlet 的请求处理方法之一进行给定调用所观察到的实例在该方法执行期间不会发生变化。当然,如果您在 doGet()
期间修改该 bean 的状态,那么您可以稍后在 doGet()
中观察到该修改。
此外,
Conversation.startConversation()
和 Conversation.endConversation()
并不做他们的名字可能让你认为他们做的事情。它们控制当前对话是“长期”还是“短暂”,这会影响其生命周期,但它们实际上并不开始或结束对话。如果您具体考虑开始和结束“长期”对话,这些名称会更有意义,但即使如此,它们也不是真正正确的。单一 setLongLived(boolean)
方法会更直观。
它应该是空的,不是吗?没有。
告诉我,也许我弄错了?
您的期望不正确。
虽然它是有效的,但在服务同一请求时多次在瞬态和长期会话之间来回切换当前会话通常没有意义。请求边界位于对话边界
内部,因此只有请求处理结束时占主导地位的对话类型才重要。
如果是这样,您能否提供一个简单的示例,它确实表明关闭对话时,与其关联的所有资源都被清除?。如果您有一个这本身不会发生
@ConversationScoped
bean,那么您可以期望在不同的对话上下文中获得不同的实例,但是 Conversation.startConversation()
和
Conversation.endConversation()
不会为当前请求提供不同的对话上下文。并且,如果您在从中获取会话上下文的生命周期结束后保留对会话范围 bean 的引用,则不应期望这会导致其属性被修改。