Метод @PostConstruct, вызываемый дважды для одного запроса
Я использую JSF 2.0 с GlassFish 3.0.
У меня есть следующий управляемый Bean:
@ManagedBean
@RequestScoped
public class OverviewController{
private List<Event> eventList;
@PostConstruct
public void init(){
System.out.println("=> OverviewController - init() - enter");
System.out.println("=< OverviewController - init() - exit");
}
}
Из файла overview.xhtml я вызываю различные атрибуты или методы из моего контрольного контроллера.
<ui:repeat var="event" value="#{overviewController.eventList}">
...
</ui:repeat>
Все работает отлично, но проблема в файле журнала:
INFO: Enter : RESTORE_VIEW 1
INFO: Exit : RESTORE_VIEW 1
INFO: Enter : RENDER_RESPONSE 6
INFO: => OverviewController - init() - enter
INFO: => Overview Controller - updateSelectedTab() - enter
INFO: =< Overview Controller - updateSelectedTab() - exit
INFO: =< OverviewController - init() - exit
INFO: => OverviewController - init() - enter
INFO: => Overview Controller - updateSelectedTab() - enter
INFO: =< Overview Controller - updateSelectedTab() - exit
INFO: =< OverviewController - init() - exit
INFO: Exit : RENDER_RESPONSE 6
Как вы можете видеть, метод init() вызывается дважды в одном запросе без всякой причины, что так всегда. Из того, что я знаю, любой метод, аннотированный с помощью PostConstruct, вызывается один раз каждый запрос. Я не прав?
EDIT:
На странице не используется AJAX.
Я проверил количество запросов с помощью firebug. Выполняются запросы дерева:
- 1.Один для javax.faces.resource(GET)
- 2.Одно для файла css (GET)
- 3.One для overview.xhtml(GET)
Ответы
Ответ 1
Это может произойти, если у вас есть несколько фреймворков, управляющих одним и тем же классом bean. Например. JSF и CDI, или JSF и Spring, или CDI и Spring и т.д. Дважды проверьте конфигурацию и аннотации на bean.
Это также может случиться, если вы используете CDI и используете несколько аннотаций @Named
во всем классе. Например, a @Named
прямо в классе, чтобы зарегистрировать его как управляемый bean, а другой - в методе get @Produces
. Вам нужно спросить себя, действительно ли это необходимо. Вы также можете просто использовать #{bean.someObject}
вместо #{someObject}
.
@Named
@RequestScoped
public class Bean {
@PostConstruct
public void init() {
// ...
}
@Named
@Produces
public SomeObject getSomeObject() {
// ...
}
}
Это также может произойти, если ваш управляемый bean расширяет некоторый абстрактный класс, который, в свою очередь, также имеет @PostConstruct
в методе. Вы должны удалить аннотацию из него. Альтернативно, вы должны сделать абстрактную процедуру init и не иметь @PostConstruct
для реализации bean:
public abstract class BaseBean {
@PostConstruct
public void postConstruct() {
init();
}
public abstract void init();
}
Ответ 2
Возможно, что оба метода init()
и @PostConstruct
срабатывают и вызывают это поведение. Попробуйте изменить имя метода init()
и/или поместив его private
. Я думаю, что это может быть связано с вашими проблемами:
http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html
Я также нашел хорошую статью об отладке жизненных циклов JSF здесь:
Отладка жизненного цикла JSF