【问题标题】:CDI ConversationScoped long-running Bean not workingCDI ConversationScoped 长时间运行的 Bean 不工作
【发布时间】:2026-02-01 19:20:06
【问题描述】:

我在理解 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>

【问题讨论】:

    标签: jsf java-ee-6 cdi jboss-weld


    【解决方案1】:

    简短回答:是的,这是正确的行为。

    长答案:对话代表一个“工作单元”,必须明确划分。这是通过对 conversation.begin() 的显式调用完成的 - 正如您已经在做的那样。如果您想在多个请求中使用相同的对话,您必须传播它 - 这是您在做的事情:-)

    当您传播对话时,会在请求中附加一个对话 ID。这告诉容器需要哪个对话。当您在请求中点击没有对话 ID 的刷新按钮时,会为每个请求生成一个新对话。

    来自文档:

    对话上下文自动 随任何 JSF faces 请求传播 (JSF 表单提交)或重定向。它 不会自动传播 非人脸请求,例如, 通过链接导航。

    如果您需要手动传播它,只需将会话ID添加到请求中即可:

    <h:link outcome="/addProduct.xhtml" value="Add Product">
       <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>
    </h:link>
    

    here 解释了所有这些以及更多内容。

    【讨论】:

    • @BalusC - 这个“清理” - 编辑什么?我的名字和“干杯”这个词有什么问题吗?我缺少任何*指令,还是您个人的喜好?我不太相信它的好处......
    • http://*.com/faq > “我可以使用签名或标语吗?”如果您不同意,请将其提交给meta