未调用JSF 2.1 ViewScopedBean @PreDestroy方法 [英] JSF 2.1 ViewScopedBean @PreDestroy method is not called
问题描述
我在视图Scoped Bean中有一个方法,该方法带有@PreDestroy
批注,另一个具有@PostConstruct
批注.
每次我导航到使用此视图范围的bean的页面时,都会正确调用@PostConstruct
方法.
但是,当我通过<h:link/>
导航到新页面(不使用该视图范围bean)时,永远不会调用@PreDestroy
方法.
我不是在谈论手动更改网址或会话结束 ,只是一个导航盒.
我想念什么?
预先感谢
这是设计使然.仅当POST操作导致导航不是回到同一视图的导航时(即,该操作方法未返回null
或void
,而是一个完全有价值的String
)导航键会立即被销毁,即使在以下情况下也是如此:只是空的.)
<h:link>
生成一个GET链接,该链接不会调用任何POST操作.由于无法在视图卸载时通过(XML)HTTP请求可靠地通知服务器端,因此无法通知JSF销毁与视图关联的视图作用域Bean.在这种情况下,只有当会话期满或会话中的最大逻辑视图数超过默认值(默认为15个)并且关联的视图是顺序中的第一个视图时,才会破坏视图作用域的bean.
如果您真的想通过导航操作销毁视图作用域的bean,那么最好的选择是由<h:commandLink>
使其成为POST请求,并通过返回导航结果来发出重定向使用?faces-redirect=true
参数.但这毕竟不是SEO友好的,因为漫游器不会索引POST链接.
我毕竟不关心该视图是否仍在会话中.如果您打算进行一些清理或记录日志,我会根据具体的功能要求寻找其他方法.
在理论中,HTML DOM onbeforeunload
事件是可能的,但这是非标准事件,并且在此期间发送ajax请求时浏览器的行为未指定事件.它有时会到达,但有时也不会.
更新:在实践中,已在信标.在主要的浏览器中运行良好.由于OmniFaces 2.3,它甚至立即破坏了相关的JSF服务器侧视图状态,并且由于OmniFaces 2.6,它甚至立即破坏了物理bean,从而进一步减少了不必要的内存使用.另请参见 JSF:Mojarra与.OmniFaces @ViewScoped:调用了@PreDestroy,但是无法对bean进行垃圾收集
I have a method in a view Scoped Bean with the @PreDestroy
annotation and another one with the @PostConstruct
annotation.
The @PostConstruct
method is properly called every time I navigate to the page that uses this view scoped bean.
However, when I navigate to a new page (which doesn't use this view scope bean) by <h:link/>
, the @PreDestroy
method is never called.
I am not talking about changing manually the url or the end of the session, just of a navigation case.
What I am missing?
Thanks in advance
This is by design. It will only be destoyed immediately when a POST action results in a navigation which isn't a postback to the same view (i.e. the action method didn't return null
or void
, but a fullworthy String
, even when just empty).
The <h:link>
generates a GET link which doesn't invoke any POST action. As it's not reliably possible to notify the server side by a (XML)HTTP request when the view is unloaded, JSF can't be notified to destroy the view scoped bean associated with the view. In such case, the view scoped bean will then only be destroyed when the session expires or when the max logical views in session has exceeded (the default is 15) and the associated view is the first in order.
If you really want to destoy the view scoped bean by a navigaiton action, then your best bet is to make it a POST request by <h:commandLink>
instead and issue a redirect by returning the navigation outcome with ?faces-redirect=true
parameter. But this is after all not SEO friendly as bots won't index POST links.
I would after all not care about the view still being in the session. If you intend to do some cleanup or logging, I'd look for alternative ways, depending on the concrete functional requirement.
In theory it would be possible by HTML DOM onbeforeunload
event, but this is a non-standard event and the browser behaviour is unspecified as to what happens when you send an ajax request during that event. It will sometimes arrive, but sometimes also not.
Update: in practice, this has been implemented in OmniFaces @ViewScoped
since OmniFaces 2.2. Initially with help of synchronous XHR and since OmniFaces 2.6 with help of beacon. It's working quite well in major browsers. Since OmniFaces 2.3 it even immediately destroys the associated JSF server side view state, and since OmniFaces 2.6 it even immediately destroys the physical beans, hereby further reducing unnecessary memory usage. See also among others JSF: Mojarra vs. OmniFaces @ViewScoped: @PreDestroy called but bean can't be garbage collected
这篇关于未调用JSF 2.1 ViewScopedBean @PreDestroy方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!