Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 2 未调用JSF 2.1 ViewScopedBean@PreDestroy方法_Jsf 2_Tomcat7_Myfaces - Fatal编程技术网

Jsf 2 未调用JSF 2.1 ViewScopedBean@PreDestroy方法

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,而是一个完整的字符串,即使该字符串为空

我在视图范围的Bean中有一个方法带有
@PreDestroy
注释,另一个方法带有
@PostConstruct
注释

每次我导航到使用此视图范围bean的页面时,都会正确调用
@PostConstruct
方法

但是,当我通过
导航到一个新页面(不使用此视图范围bean)时,将永远不会调用
@PreDestroy
方法

我不是说,只是指一个导航案例

我错过了什么


提前感谢

这是精心设计的。只有当POST操作导致导航不是回发到同一视图时(即操作方法没有返回
null
void
,而是一个完整的
字符串
,即使该字符串为空),才会立即解除锁定

生成一个GET链接,该链接不调用任何POST操作。由于卸载视图时无法可靠地通过(XML)HTTP请求通知服务器端,因此无法通知JSF销毁与视图关联的视图范围bean。在这种情况下,视图作用域bean将仅在会话过期或会话中的最大逻辑视图已超过(默认值为15)且关联视图是第一个顺序时销毁

如果您真的想通过navigaiton操作来解除视图范围bean的绑定,那么最好的办法是通过
将其作为POST请求,并通过使用
?faces redirect=true
参数返回导航结果来发出重定向。但这毕竟不利于搜索引擎优化,因为机器人不会索引帖子链接

毕竟,我不会在意仍在讨论中的观点。如果您打算进行一些清理或日志记录,我会根据具体的功能需求寻找替代方法

理论上,HTML DOM
onbeforeunload
事件可以实现这一点,但这是一个非标准事件,浏览器行为未指定在该事件期间发送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:我在这里提出一个问题: