gpt4 book ai didi

jsf-2 - 为什么过期的@ViewScoped bean 在 session 过期之前不会被销毁

转载 作者:行者123 更新时间:2023-12-04 12:54:20 25 4
gpt4 key购买 nike

我在 GlassFish 4 和 Java 7 上使用 Mojarra 2.2.4。

我从 BalusC 对 How and when is a @ViewScoped bean destroyed in JSF? 的回答中了解到,@ViewScoped beans 应该在三种情况下被销毁:

  • 具有非空结果的回传
  • session 到期
  • 超过 session 中的最大逻辑 View 数

  • 我的 bean 在前两种情况下被销毁,但在超过逻辑 View 的最大数量时不会被销毁。我已经验证了当超过最大值时 bean 确实会过期(我收到 ViewExpiredException),但是在 session 本身过期之前它们仍然不会被销毁。

    出于内存消耗的原因,我希望在第三种情况下销毁 bean,特别是因为它们在过期后不可用。

    问题
  • 为什么 bean 过期后没有销毁?
  • 这是错误还是预期行为?
  • 什么是确保 bean 被破坏的干净解决方法?
  • 更新: OmniFaces ViewScoped annotation bean 过期后立即销毁。

  • 最小的例子

    这是我的 bean :
    @javax.inject.Named("sandboxController")
    @javax.faces.view.ViewScoped
    public class SandboxController implements Serializable {
    private static final Logger log = Logger.getLogger(SandboxController.class.getName());
    @PostConstruct
    public void postConstruct() {
    log.log(Level.INFO, "Constructing SandboxController");
    }
    @PreDestroy
    public void preDestroy() {
    log.log(Level.INFO, "Destroying SandboxController");
    }
    public String getData() {
    return "abcdefg";
    }
    }

    和我的 sandbox.xhtml:
    <?xml version='1.0' encoding='UTF-8' ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html">
    <body>
    <h:form>
    <h:outputText value="#{sandboxController.data}"/>
    </h:form>
    </body>
    </html>

    和我的 web.xml 的一部分:
    <context-param>  
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>3</param-value>
    </context-param>
    <context-param>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>3</param-value>
    </context-param>

    如果我刷新 sandbox.xhtml 50 次,我会得到 50 份 INFO: Constructing SandboxController在日志中。无论刷新多少次, bean 都不会被破坏。 VisualVM 确认这些 bean 仍然被 UIViewRoot 的 ViewMap 引用。在我的全尺寸 bean 中,它保持了相当多的状态,我很快得到一个 OutOfMemoryException。

    当我手动使 session 过期时,我得到了 50 个 INFO: Destroying SandboxController 的副本。 .

    如果我向 sandbox.xhtml 添加一个提交按钮并在 4 个不同的选项卡中加载它,然后尝试提交第一个,我得到一个 ViewExpiredException,正如预期的那样,但 bean 仍然没有被破坏。

    如果我改为使用 javax.faces.bean.ManagedBean 和 javax.faces.view.ViewScoped 注释,则行为是相同的。但是,OmniFaces 注释 org.omnifaces.cdi.ViewScoped 可以正常工作。

    澄清...

    我的@ViewScoped bean 在 session 到期时被销毁,这与相关问题中描述的问题不同,例如 Linked ViewScoped beans lead to memory leaks

    我不是问为什么每个 bean 在后续刷新时不会立即销毁,如此处所质疑: JSF 2.1 ViewScopedBean @PreDestroy method is not called .我想知道为什么即使它们过期并且不再有用,它们仍然没有被破坏,从而继续消耗内存。

    最佳答案

    通过使用 OmniFaces @ViewScoped 注释 ( org.omnifaces.cdi.ViewScoped ) 而不是标准的 @ViewScoped ( javax.faces.view.ViewScoped ),我找到了一个干净的解决方法。

    OmniFaces ViewScoped 会在 bean 过期后立即正确销毁它们。

    请参阅此处了解更多详情:
    http://showcase.omnifaces.org/cdi/ViewScoped

    关于jsf-2 - 为什么过期的@ViewScoped bean 在 session 过期之前不会被销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20930396/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com