JSF中的@ViewScoped bean何时销毁?销毁方式是怎样的?

17

@RequestScoped@SessionScopedBean的生命周期由Servlet容器自己管理,因为它们基本上被存储为HttpRequestHttpSession的属性。那么JSF如何管理@ViewScopedBean的生命周期呢?我知道它在视图创建时被创建,并且在提交到不同视图的postback之前可用。但是我发现,在我们从该视图移动后,它并不会立即被垃圾回收。


一旦托管的Bean操作方法返回有效的导航案例结果,即使是到同一个视图,视图范围的托管Bean也将被垃圾回收并重新创建。请阅读此文http://balusc.blogspot.co.il/2011/09/communication-in-jsf-20.html,这是它们存储的位置:https://dev59.com/PWox5IYBdhLWcg3wf0VP#9177769。 - Daniel
实际上,你不应该能够预测gc或立即发生gc,对于mojarra中的viewscoped beans,请参见https://dev59.com/pGrWa4cB1Zd3GeqP7R1r#13097208。 - kolossus
垃圾回收是异步的。当视图范围被“销毁”时,它实际上只是像所有其他Java对象一样“标记为准备进行垃圾回收”。注意:标记实际上是一个引用计数器为0(即标记为“不再使用”)。 - DwB
1个回答

34

在以下情况下,它将被销毁:

  • 执行非null结果的postback时

  • 或者,在会话中的逻辑视图数已超过且特定视图是LRU链中的第一个(在Mojarra中,这可以通过com.sun.faces.numberOfViewsInSessioncom.sun.faces.numberOfLogicalViews上下文参数进行配置,每个默认值为15)

  • 或者,会话中的活动视图范围数量已超限(在Mojarra中,这是硬编码的限制为25),另请参见JSF 2.2 Memory Consumption: Why does Mojarra keep the ViewScoped Beans of the last 25 Views in Memory?

  • 或者,会话已过期。

因此,当页面通过单击GET链接到另一页、刷新页面或关闭浏览器选项卡/窗口而卸载时,它不会被销毁。该bean将生存到满足上述条件之一为止。如果要在卸载时销毁它,请考虑改用OmniFaces @ViewScoped


2
  1. 是的。它们存储在一个LRU映射中,按最后使用顺序排序。最近最少使用的是第一个条目。
  2. 请参见https://dev59.com/JWcs5IYBdhLWcg3w0HIa#12564632
- BalusC
@BalusC,有没有更快地销毁ViewScoped beans的解决方案?使用Omnifaces的ViewScoped注释会有帮助吗? - Mahmoud Saleh
1
在Icefaces中有一个注释@WindowDisposed。当浏览器关闭自身时,视图将被垃圾回收。 - Vishnudev K
@BalusC,类似以下代码会强制销毁视图作用域的Bean:FacesContext.getCurrentInstance().getViewRoot().getViewMap().clear(); 例如,在单击提交按钮后,将处理请求,然后向用户显示成功消息。 - Mahmoud Saleh
@Mahmoud:不是的。视图作用域的Bean被存储在会话中。 - BalusC
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接