Метод @PostConstruct, вызываемый дважды для одного запроса - программирование
Подтвердить что ты не робот

Метод @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)
4b9b3361

Ответ 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