Когда использовать f: viewAction / preRenderView вместо PostConstruct?

96

Когда следует использовать событие f:viewActionили preRenderViewдля инициализации данных для страницы, а не @PostConstructаннотацию? Является ли обоснование использовать тот или иной компонент, основанный на типе области действия компонента поддержки, например, если компонент поддержки есть @RequestScoped, то будет ли выбор использования f:viewActionили preRenderViewболее @PostConstructдля инициализации вашего компонента поддержки до рендеринга представления неуместным, поскольку эти два будут привести к такому же эффекту?

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()
    {

    }
}
Лучшие практики
источник

Ответы:

119

Когда следует использовать событие f: viewAction или preRenderView для инициализации данных для стихов страницы с помощью аннотации @PostConstruct?

Используйте, <f:viewAction>если вы хотите выполнить метод до отображения HTML. Это особенно полезно, если вы хотите выполнять действия на основе значений модели, установленных на <f:viewParam>этапе обновления значений модели. А именно они недоступны на данный момент @PostConstruct. В JSF 2.0 / 2.1 этого тега не существовало, и вы должны использовать preRenderViewобходной путь.

Если вспомогательный компонент - это @RequestScoped, действительно ли они делают то же самое? (так что тогда выбор разработчика? (@PostConstruct кажется «чище»).

Нет, они точно не делают то же самое. @PostConstructЯвляется intented для выполнения действий непосредственно после строительства бин и установки всех инжектированных зависимостей и управляемых свойств , таких как @EJB, @Inject, @ManagedPropertyи т.д. А именно, инъецированные зависимости не доступны внутри конструктора компонента. Таким образом, это будет запускаться только один раз для каждого представления, сеанса или приложения, когда компонент имеет область видимости, сеанса или приложения. По <f:viewAction>умолчанию он вызывается только при начальном запросе GET, но может onPostback="true"быть настроен через атрибут для вызова и при запросах обратной передачи. preRenderViewСобытие вызывается при каждом запросе HTTP (да, это также включает в себя Ajax запросов!).

Обобщенная, использование , @PostConstructесли вы хотите выполнить действия по инжектированных зависимостей и управляемых свойств , которые задаются @EJB, @Inject, @ManagedPropertyи т.д. во время строительства бина. Используйте, <f:viewAction>если вы также хотите выполнять действия со свойствами, установленными <f:viewParam>. Если вы все еще используете JSF 2.0 / 2.1, используйте preRenderViewвместо <f:viewAction>. При необходимости вы можете добавить проверку FacesContext#isPostback()для выполнения preRenderViewдействия только по первоначальному запросу.

Смотрите также:

BalusC
источник
Спасибо. Извините, я редактировал свой исходный вопрос, пока вы писали ответ ...
BestPractices
Я упомянул область действия bean-компонента, потому что @PostConstruct будет вызываться только один раз, если bean-компонент был SessionScoped (во время первого создания bean-компонента), но preRenderView будет вызываться каждый раз при доступе к странице. Или я ошибся?
BestPractices
Да, это правильно. Событие предварительного просмотра вызывается на этапе вызова действия. Пост-конструкция вызывается после построения bean-компонента. Компонент с областью действия сеанса не создается для каждого HTTP-запроса.
BalusC
Мне было интересно, что мой метод вызывается во время запросов ajax. вызов isPostBack () спас положение !!
jacosta
Для полноты картины следует упомянуть Omnifaces'@Param : «Для HTTP параметры запроса , это в основном , как <f:viewParam>, но с большей разницей , что впрыскивается параметр непосредственно доступен во время @PostConstruct, что позволяет гораздо более простой способ обработки без необходимости выработки <f:event type="preRenderView">или <f:viewAction>в Посмотреть."
Йенс Пьегса,
1

Вам нужно инициализировать свойства управляемого bean-компонента? -> Затем используйте @ PostConstruct. В противном случае вам нужно работать с параметрами, переданными из другого представления? -> Затем используйте « preRenderView »

Валь Мартинес
источник