即使已经实例化了 ManagedBean(例如在 AJAX 调用上),也会调用 @PostConstruct 方法[重复]

Posted

技术标签:

【中文标题】即使已经实例化了 ManagedBean(例如在 AJAX 调用上),也会调用 @PostConstruct 方法[重复]【英文标题】:@PostConstruct method is called even if the ManagedBean has already been instantiated (e.g. on AJAX-calls) [duplicate] 【发布时间】:2012-02-06 22:13:45 【问题描述】:

我有一个@ViewScope ManagedBean 和一个@PostConstruct 初始化方法。此方法在创建新实例时调用,但也在每次 ajax 调用时调用。为什么会这样?

在 AJAX 调用中,会调用并执行 init-Method,但看不到任何更改。例如,如果我在 init-Method 中更改了一个属性,这仅在实例化时可见,而对于 AJAX 调用不可见。对于 AJAX 调用,值更改不会在 @ViewScoped Bean 中持久化。

谁能说出为什么会这样?我该如何更改?

【问题讨论】:

@PeterGwiazda 但没有真正回答。 好的。我的评论是一样的:粘贴您的 JSF 页面。看起来视图根已重新创建。例如,当您尝试在 JSF 代码中使用 JSTL(例如 c:if)时,就会发生这种情况。 @PeterGwiazda 我的代码太大,无法粘贴到这里。我将尝试创建一个简短的版本。我在我的所有视图范围的 bean 中都遇到了这种行为。如果有帮助,我还会使用 <ui:include> 和 Richfaces。 【参考方案1】:

这不是正常行为。如果在打开部分状态保存时将标记处理程序属性或 JSF 组件的 binding 属性绑定到视图范围 bean 的属性,则会发生这种情况。这被称为issue 1492,已在(即将推出的)Mojarra 2.2 中修复。

通常,您可以通过缺少rendered 属性来识别标记处理程序。例如。 <c:if><f:validator><ui:include> 等。如果将此类标记处理程序的属性绑定到视图范围 bean 的属性,如下所示

<c:if test="#viewScopedBean.something"></c:if>
<h:inputText><f:validator binding="#viewScopedBean.validate" /></h:inputText>
<ui:include src="#viewScopedBean.includePage" />

然后每次从部分保存的状态恢复视图时,都会重新创建视图范围的 bean。这是视图范围的鸡蛋问题,因为为了获得 right 视图范围的 bean,必须从恢复的视图中提取它。

如果您在 JSF 组件的 binding 属性中引用视图范围 bean 的属性,也会发生这种情况。

<h:someComponent binding="#viewScopedBean.someComponent" />

另见:

Communication in JSF 2.0 - @ViewScoped fails in tag handlers

【讨论】:

非常感谢。情况就是这样。我在每个视图中都有一个&lt;c:set var="someVar" value="#myBean.someVar" /&gt;。我会尝试你的一些解决方案。 您可以使用&lt;ui:param&gt; 代替长EL 表达式的别名。 这个问题确实有点复杂。将部分状态保存方法设置为 false 对我有用。其他解决方案并不那么容易使用,因为不知道是这样,有很多地方我使用这种绑定。升级到最新的 JSF 版本并不能开箱即用。可能这将是未来的最佳解决方案。不过,非常感谢您的回答和解释!问题已回答。 我的解决方案是在视图范围的 bean 中只保留用户输入和操作侦听器(它们使用用户输入)。它通常是每页一个视图 bean。其他一切 - 组件绑定、可能的选项(用于组合框、列表等)我保留在请求范围的 bean 中。只有在必要时才使用会话处理 bean。我从不使用 JSTL——它在 JSF 中毫无意义。这就像在编译期间更改 JSF 代码一样。如果您使用 JSTL,那么恢复视图是没有意义的。遵守这些规则使我一切顺利。

以上是关于即使已经实例化了 ManagedBean(例如在 AJAX 调用上),也会调用 @PostConstruct 方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

发生验证错误后,如何使用 PrimeFaces AJAX 填充文本字段?

单体内置对象

第五章 单体内置对象

单体内置对象的理解

Java ManagedBean 方法可以返回 null 吗?

如何在 JSF 2.0/2.1 中用 CDI 替换 @ManagedBean / @ViewScope