我在理解Weld或CDI的会话范围时遇到了一些问题。
在我的JSF Faclets页面中,我打电话:
<f:metadata>
<f:event type="preRenderView" listener="#{viewBean.start}" />
</f:metadata>
豆子:
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
@Named
@ConversationScoped
public class ViewBean implements Serializable {
@Inject
private Conversation conversation;
public void start() {
if (conversation.isTransient()) {
System.out.println("START CONVERSATION");
conversation.begin();
}
}
现在每次刷新浏览器时,都会启动一个新的对话。这是正确的行为吗?那么为什么谈话总是短暂的?没有异常被抛出。 beans.xml已创建并为空:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
答案 0 :(得分:5)
简短回答:是的,这是正确的行为。
长答案:对话代表一个“工作单元”,必须明确区分。这是通过显式调用conversation.begin()完成的 - 就像你已经做的那样。如果您想对多个请求使用相同的对话,则必须传播 - 这就是不所做的事情: - )
传播对话时,会话ID会附加到请求中。这告诉容器需要哪个对话。当您在请求中点击没有会话ID的刷新按钮时,会为每个请求生成一个新会话。
来自文档:
自动对话上下文 传播任何JSF面部请求 (JSF表单提交)或重定向。它 不会自动传播 例如,非面孔请求 通过链接导航。
如果您需要手动传播,只需将conversation-id添加到请求中:
<h:link outcome="/addProduct.xhtml" value="Add Product">
<f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>
</h:link>
here解释了所有这些以及更多内容。