JSF 2.1 ViewScopedBean @PreDestroy 方法未被调用 [英] JSF 2.1 ViewScopedBean @PreDestroy method is not called

查看:32
本文介绍了JSF 2.1 ViewScopedBean @PreDestroy 方法未被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在视图 Scoped Bean 中有一个方法,带有 @PreDestroy 注释,另一个方法带有 @PostConstruct 注释.

I have a method in a view Scoped Bean with the @PreDestroy annotation and another one with the @PostConstruct annotation.

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

The @PostConstruct method is properly called every time I navigate to the page that uses this view scoped bean.

但是,当我通过 <h:link/> 导航到新页面(不使用此视图范围 bean)时,@PreDestroy方法永远不会被调用.

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.

我不是在谈论 手动更改 url 或会话结束,只是一个导航案例.

I am not talking about changing manually the url or the end of the session, just of a navigation case.

我缺少什么?

提前致谢

推荐答案

这是设计使然.它只会在 POST 操作导致导航不是回发到同一视图时立即销毁(即操作方法没有返回 nullvoid,但是一个完整的String,即使只是空的).

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).

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

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.

如果您真的想通过导航操作来破坏视图范围的 bean,那么最好的办法是通过 <h:commandLink> 使其成为 POST 请求而是通过返回带有 ?faces-redirect=true 参数的导航结果来发出重定向.但这毕竟不是 SEO 友好的,因为机器人不会索引 POST 链接.

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.

理论中,HTML DOM onbeforeunload 事件是可能的,但这是一个非标准事件,浏览器行为未指定发送时会发生什么该事件期间的 ajax 请求.它有时会到达,但有时也不会.

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.

更新:在实践中,这已在OmniFaces @ViewScoped 自 OmniFaces 2.2 起.最初在 同步 XHR 和自 OmniFaces 2.6 起在 信标.它在主要浏览器中运行良好.从 OmniFaces 2.3 开始,它甚至会立即破坏相关联的 JSF 服务器端视图状态,从 OmniFaces 2.6 开始,它甚至会立即破坏物理 bean,从而进一步减少不必要的内存使用.另见其他JSF:Mojarra vs. OmniFaces @ViewScoped:@PreDestroy 被调用但 bean 不能被垃圾回收

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆