Jsf 2 未调用JSF 2.1 ViewScopedBean@PreDestroy方法
我在视图范围的Bean中有一个方法带有Jsf 2 未调用JSF 2.1 ViewScopedBean@PreDestroy方法,jsf-2,tomcat7,myfaces,Jsf 2,Tomcat7,Myfaces,我在视图范围的Bean中有一个方法带有@PreDestroy注释,另一个方法带有@PostConstruct注释 每次我导航到使用此视图范围bean的页面时,都会正确调用@PostConstruct方法 但是,当我通过导航到一个新页面(不使用此视图范围bean)时,将永远不会调用@PreDestroy方法 我不是说,只是指一个导航案例 我错过了什么 提前感谢这是精心设计的。只有当POST操作导致导航不是回发到同一视图时(即操作方法没有返回null或void,而是一个完整的字符串,即使该字符串为空
@PreDestroy
注释,另一个方法带有@PostConstruct
注释
每次我导航到使用此视图范围bean的页面时,都会正确调用@PostConstruct
方法
但是,当我通过
导航到一个新页面(不使用此视图范围bean)时,将永远不会调用@PreDestroy
方法
我不是说,只是指一个导航案例
我错过了什么
提前感谢这是精心设计的。只有当POST操作导致导航不是回发到同一视图时(即操作方法没有返回
null
或void
,而是一个完整的字符串
,即使该字符串为空),才会立即解除锁定
生成一个GET链接,该链接不调用任何POST操作。由于卸载视图时无法可靠地通过(XML)HTTP请求通知服务器端,因此无法通知JSF销毁与视图关联的视图范围bean。在这种情况下,视图作用域bean将仅在会话过期或会话中的最大逻辑视图已超过(默认值为15)且关联视图是第一个顺序时销毁
如果您真的想通过navigaiton操作来解除视图范围bean的绑定,那么最好的办法是通过
将其作为POST请求,并通过使用?faces redirect=true
参数返回导航结果来发出重定向。但这毕竟不利于搜索引擎优化,因为机器人不会索引帖子链接
毕竟,我不会在意仍在讨论中的观点。如果您打算进行一些清理或日志记录,我会根据具体的功能需求寻找替代方法
理论上,HTML DOMonbeforeunload
事件可以实现这一点,但这是一个非标准事件,浏览器行为未指定在该事件期间发送ajax请求时会发生什么。它有时会到来,但有时也不会
更新:实际上,自OmniFaces 2.2以来,该功能已在中实现。最初是在OmniFaces 2.6的帮助下,后来是在的帮助下。它在主流浏览器中运行得很好。由于OmniFaces 2.3,它甚至会立即销毁相关的JSF服务器端视图状态,而由于OmniFaces 2.6,它甚至会立即销毁物理bean,从而进一步减少不必要的内存使用。另请参见我准备了一个小的NetBeans项目,演示在不同的导航情况下(对于Mojarra 2.2.9、Glassfish4、NetBeans8.0.2、JDK1.7),何时发布JSF2.2 CDI兼容的@ViewScoped bean(javax.faces.view.ViewScoped)进行垃圾收集。这里省略了代码,请看下载 下图总结了处理的导航案例和结果: 要监视@ViewScoped bean,请对Glassfish使用VisualVM(或迷你项目上的内置NetBeans分析器),并在包名“webel.com.jsf”上过滤采样器内存堆直方图类视图。下图显示了一个荒谬的66个实例 webel.com.jsf.Jsf22ViewBean在对h:link、浏览器URL获取和浏览器重新加载获取进行大量实验后,哪些实例不会被垃圾收集(您可以使用VisualVM执行GC按钮进行测试):
相比之下,使用h:commandButton和动作方法表达式或动作字符串从index.xhtml(一次使用@ViewScoped bean读取简单EL变量)导航到done.xhtml(根本不使用bean)会导致@ViewScoped bean被释放用于垃圾收集(WeldClientProxy始终有一个对@ViewScope bean的引用,当您使用h:commandButton来回导航时,WeldClientProxy从一个可发布bean移动到下一个bean).一个小的修正是正确的。即使你做了一个重定向,如果你重定向到POST请求起源的同一个视图,JSF将不会破坏视图范围的bean。对于要破坏的视图范围的bean,你需要在POST请求处理完后呈现一个完全不同的视图。如果我理解的很好,用一个信标离开视图的
@PreDestroy
可能会在新加载视图的@PostConstruct
之后调用?ForguesR:是的,它彼此是异步的。以上回答了这个问题(进一步基于BalusC的回答)通过详尽地演示各种导航案例,但它没有解释如何处理产生的不会进行垃圾收集的“悬空”@viewscope bean:我在这里提出一个问题: