何时使用 f: viewAction/preRenderView 与 PostConstruction?

与使用 @PostConstruct注释相比,什么时候应该使用 f:viewActionpreRenderView事件来初始化页面的数据?是基于后台 bean 的作用域类型使用其中一种的基本原理,例如。如果后台 bean 是 @RequestScoped,那么在呈现视图之前选择使用 f:viewAction或者 preRenderView而不是 @PostConstruct来初始化您的后台 bean 是否无关紧要,因为两者会导致同样的效果?

ViewAction 或 preRenderView

<f:metadata>
<f:viewAction action="#{myBean.initialize}" />
</f:metadata>
<f:metadata>
<f:event type="preRenderView" listener="#{myBean.initialize}"/>
</f:metadata>

或者

@ PostConstruction

public class MyBean
{
@PostConstruct
public void initialize()
{


}
}
78228 次浏览

When should one use the f:viewAction or preRenderView event to initialize data for a page verses using the @PostConstruct annotation?

Use the <f:viewAction> when you want to execute a method before the HTML is been rendered. This is particularly useful if you want to perform actions based on model values set by <f:viewParam> during update model values phase. Namely, they are not available at the moment the @PostConstruct runs. In JSF 2.0/2.1, this tag didn't exist and you have to use the preRenderView workaround.

If the backing bean is @RequestScoped, do they effectively do the exact same thing? (and so then it is up to developer choice? (@PostConstruct seems "cleaner").

No, they do definitely not effectively do the same thing. The @PostConstruct is intented to perform actions directly after bean's construction and setting of all injected dependencies and managed properties such as @EJB, @Inject, @ManagedProperty, etc. Namely, the injected dependencies are not available inside the bean's constructor. This will thus run only once per view, session or application when the bean is view, session or application scoped. The <f:viewAction> is by default only invoked on initial GET request, but can via onPostback="true" attribute be configured to be invoked on postback requests as well. The preRenderView event is invoked on every HTTP request (yes, this also includes ajax requests!).

Summarized, use @PostConstruct if you want to perform actions on injected dependencies and managed properties which are set by @EJB, @Inject, @ManagedProperty, etc during bean's construction. Use <f:viewAction> if you @EJB0 want to perform actions on properties set by <f:viewParam>. If you're still on JSF 2.0/2.1, use preRenderView instead of <f:viewAction>. You can if necessary add a check on FacesContext#isPostback() to perform the preRenderView action on initial request only.

See also:

Do you need to initialize managed bean's properties? --> Then, use @PostConstruct Otherwise, do you need to work with params passed from other view? --> Then, use "preRenderView"