Quando usar f: viewAction / preRenderView versus PostConstruct?

95

Quando se deve usar o evento f:viewActionou preRenderViewpara inicializar os dados de uma página em vez de usar a @PostConstructanotação? A justificativa para usar um ou outro é baseada no tipo de escopo do bean de apoio, por exemplo, se o bean de apoio for @RequestScoped, então a escolha de usar f:viewActionou preRenderViewover @PostConstructpara inicializar seu bean de apoio antes de renderizar a visualização seria irrelevante como os dois seriam resultar no mesmo efeito?

f: viewAction ou preRenderView

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

ou

@PostConstruct

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

    }
}
Melhores Práticas
fonte

Respostas:

117

Quando se deve usar o evento f: viewAction ou preRenderView para inicializar dados para uma página em versos usando a anotação @PostConstruct?

Use <f:viewAction>quando quiser executar um método antes de o HTML ser renderizado. Isso é particularmente útil se você deseja executar ações com base nos valores do modelo definidos por <f:viewParam>durante a fase de atualização dos valores do modelo. Ou seja, eles não estão disponíveis no momento da @PostConstructexecução. No JSF 2.0 / 2.1, essa tag não existia e você deve usar a preRenderViewsolução alternativa.

Se o bean de apoio for @RequestScoped, eles fazem exatamente a mesma coisa? (e então fica a critério do desenvolvedor? (@PostConstruct parece "mais limpo").

Não, eles definitivamente não fazem a mesma coisa. A @PostConstructé intented para executar acções directamente após a construção do feijão e configuração de todas as dependências injectados e propriedades de gestão, tais como @EJB, @Inject, @ManagedProperty, etc. Nomeadamente, as dependências injectados não estão disponíveis dentro construtor do feijão. Assim, ele será executado apenas uma vez por visualização, sessão ou aplicativo quando o bean tiver o escopo de visualização, sessão ou aplicativo. O <f:viewAction>é, por padrão, chamado apenas na solicitação GET inicial, mas pode onPostback="true"ser configurado por meio do atributo para ser chamado também nas solicitações de postback. O preRenderViewevento é invocado em cada solicitação HTTP (sim, isso também inclui solicitações ajax!).

Resumida, o uso @PostConstructse você quiser executar ações em dependências injetadas e propriedades gerenciadas que são definidas por @EJB, @Inject, @ManagedProperty, etc durante a construção do feijão. Use <f:viewAction>se também quiser realizar ações nas propriedades definidas por <f:viewParam>. Se você ainda estiver no JSF 2.0 / 2.1, use em preRenderViewvez de <f:viewAction>. Você pode, se necessário, adicionar uma verificação FacesContext#isPostback()para executar a preRenderViewação apenas na solicitação inicial.

Veja também:

BalusC
fonte
Obrigado. Desculpe, eu editei minha pergunta original enquanto você escrevia a resposta ...
BestPractices
Mencionei o escopo do bean porque @PostConstruct seria chamado apenas uma vez se o bean fosse SessionScoped (no momento em que o bean é criado pela primeira vez), mas preRenderView seria chamado sempre que a página fosse acessada. Ou eu entendi errado?
BestPractices
Sim esta correto. O evento de visualização de pré-renderização é chamado na fase de ação de chamada. A pós-construção é chamada após a construção do bean. Um bean com escopo de sessão não é construído em cada solicitação HTTP.
BalusC
Eu queria saber se meu método estava sendo chamado durante as solicitações de Ajax. a chamada isPostBack () salvou o dia !!
jacosta
1

Você precisa inicializar as propriedades do bean gerenciado? -> Então, use @ PostConstruct Caso contrário, você precisa trabalhar com parâmetros passados ​​de outra visão? -> Em seguida, use " preRenderView "

Val Martinez
fonte