何时使用 f:viewAction / preRenderView 与 PostConstruct?
Posted
技术标签:
【中文标题】何时使用 f:viewAction / preRenderView 与 PostConstruct?【英文标题】:When to use f:viewAction / preRenderView versus PostConstruct? 【发布时间】:2012-04-08 07:51:30 【问题描述】:什么时候应该使用f:viewAction
或preRenderView
事件来初始化页面的数据而不是使用@PostConstruct
注释?是否基于支持 bean 的范围类型使用其中一个或另一个的基本原理,例如如果支持 bean 是 @RequestScoped
,那么在渲染视图之前选择使用 f:viewAction
或 preRenderView
而不是 @PostConstruct
来初始化支持 bean 是否无关紧要,因为两者会产生相同的效果?
f:viewAction 或 preRenderView
<f:metadata>
<f:viewAction action="#myBean.initialize" />
</f:metadata>
<f:metadata>
<f:event type="preRenderView" listener="#myBean.initialize"/>
</f:metadata>
或
@PostConstruct
public class MyBean
@PostConstruct
public void initialize()
【问题讨论】:
【参考方案1】:什么时候应该使用 f:viewAction 或 preRenderView 事件来初始化页面的数据,而不是使用 @PostConstruct 注解?
如果您想在呈现 html 之前执行方法,请使用 <f:viewAction>
。如果您想在更新模型值阶段根据<f:viewParam>
设置的模型值执行操作,这将特别有用。也就是说,它们在@PostConstruct
运行时不可用。在 JSF 2.0/2.1 中,此标记不存在,您必须使用 preRenderView
解决方法。
如果支持 bean 是 @RequestScoped,它们是否有效地做完全相同的事情? (所以这取决于开发人员的选择?(@PostConstruct 似乎“更干净”)。
不,他们肯定不会有效地做同样的事情。 @PostConstruct
旨在在 bean 构造和设置所有注入的依赖项和托管属性(例如 @EJB
、@Inject
、@ManagedProperty
等)之后执行操作直接。即注入的依赖项在 bean 的构造函数中不可用。因此,当 bean 是视图、会话或应用程序范围时,每个视图、会话或应用程序将只运行一次。 <f:viewAction>
默认情况下仅在初始 GET 请求时调用,但也可以通过 onPostback="true"
属性配置为在回发请求时调用。在每个 HTTP 请求上都会调用 preRenderView
事件(是的,这也包括 ajax 请求!)。
总结一下,如果你想在 bean 的构建过程中对注入的依赖项和由@EJB
、@Inject
、@ManagedProperty
等设置的托管属性执行操作,请使用 @PostConstruct
。如果您还想对<f:viewParam>
设置的属性执行操作,请使用<f:viewAction>
。如果您仍在使用 JSF 2.0/2.1,请使用 preRenderView
而不是 <f:viewAction>
。如有必要,您可以在 FacesContext#isPostback()
上添加检查,以仅在初始请求时执行 preRenderView
操作。
另见:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for? ViewParam vs @ManagedProperty(value = "#param.id") Is it possible to disable f:event type="preRenderView" listener on postback?【讨论】:
谢谢。抱歉,我在您写回复时编辑了我原来的问题... 我提到了 bean 范围,因为如果 bean 是 SessionScoped(在第一次创建 bean 时),@PostConstruct 只会被调用一次,但每次访问页面时都会调用 preRenderView。还是我弄错了? 是的,没错。在调用动作阶段调用预渲染视图事件。 post 构造在 bean 构造之后被调用。不是在每个 HTTP 请求上都构建会话范围的 bean。 我想知道我的方法在 ajax 请求期间被调用。 isPostBack() 调用拯救了这一天!! 为了完整起见,我们应该提到Omnifaces'@Param
:“对于HTTP请求参数,它基本上类似于<f:viewParam>
,但主要区别在于注入参数在@PostConstruct
期间直接可用,无需在视图中使用<f:event type="preRenderView">
或<f:viewAction>
,就可以更轻松地进行处理。"【参考方案2】:
您需要初始化托管 bean 的属性吗? --> 然后,使用@PostConstruct 否则,您是否需要使用从其他视图传递的参数? --> 然后,使用“preRenderView”
【讨论】:
以上是关于何时使用 f:viewAction / preRenderView 与 PostConstruct?的主要内容,如果未能解决你的问题,请参考以下文章
在使用 p:commandButton 导航时调用 f:viewAction 中的操作
根据 f:viewParam 有条件地调用 f:viewAction