Компоненты с областью действия сеанса и @PostConstruct в JSF

Довольно простой и понятный вопрос.

У меня есть управляемый компонент с ограниченным объемом сеанса, как показано ниже (демонстрирующий слайдер диапазона PrimeFaces).

@ManagedBean
@SessionScoped
public final class RangeSliderBean implements Serializable
{
    private static final long serialVersionUID = 1L;
    private static final byte scale=2;

    private BigDecimal maxPrice;
    private BigDecimal minPrice;

    public RangeSliderBean()
    {
        maxPrice=new BigDecimal(100).setScale(scale, RoundingMode.HALF_UP);
        minPrice=new BigDecimal(5).setScale(scale, RoundingMode.HALF_UP);
    }

    @PostConstruct
    private void init()
    {

    }

    //Mutators and accessors
}

Указанные два поля в указанном выше управляемом компоненте с привязкой к сеансу привязаны к странице XHTML.

<h:form id="rangeForm" prependId="true">
    <p:panel header="Shop by Price">
        <h:panelGrid id="rangeSliderPanelGrid" columns="1" style="margin-bottom:10px">
            <h:outputText id="displayRange" value="Min : #{rangeSliderBean.minPrice.toPlainString()} Max : #{rangeSliderBean.maxPrice.toPlainString()}"/>

            <p:slider for="txtMinPrice, txtMaxPrice" 
                      minValue="#{rangeSliderBean.minPrice}" 
                      maxValue="#{rangeSliderBean.maxPrice}" 
                      display="displayRange" 
                      style="width:170px" 
                      range="true" displayTemplate="Min : {min} Max : {max}"/>
        </h:panelGrid>

        <h:inputHidden id="txtMinPrice" value="#{rangeSliderBean.minPrice}" converter="#{bigDecimalConverter}"/>
        <h:inputHidden id="txtMaxPrice" value="#{rangeSliderBean.maxPrice}" converter="#{bigDecimalConverter}"/>
        <p:commandButton value="Submit"/> <!--Update/process is temporarily omitted.-->
    </p:panel>
</h:form>

Если эти поля инициализируются в методе, помеченном @PostConstruct, т.е. init(), в этом случае (вместо инициализации их в конструкторе, как показано во фрагменте) их указанные значения не установлены до тех пор, пока пользователь входит в систему (если сеанс не создан).

Как же тогда они могут быть инициализированы в конструкторе, небольшая путаница? (Я знаю, что конструктор вызывается до вызова метода, аннотированного @PostConstruct).


person Tiny    schedule 06.12.2013    source источник
comment
Если эти поля инициализируются в методе, помеченном @PostConstruct, т.е. init() (...), их указанные значения не устанавливаются, пока пользователь не войдет в систему, обратите внимание, что метод, аннотированный @PostConstruct, будет вызываться после создания управляемый компонент и после внедрения других компонентов, например EJB. Не могли бы вы иначе привести пример такого странного поведения?   -  person Luiggi Mendoza    schedule 07.12.2013
comment
метод, помеченный @PostConstruct, будет вызван после создания управляемого bean. Это то же самое, что сказать, метод, аннотированный @PostConstruct, будет вызываться после вызова конструктора. ... и после инъекции других компонентов, например EJB. Это также происходит после создания управляемого bean-компонента (т.е. после того, как конструктор завершил свою работу). Другой пример представить не могу :).   -  person Tiny    schedule 07.12.2013
comment
Я имею в виду: опубликуйте действительный код JSF / Facelets, используя ваш @SessionScoped управляемый компонент, который демонстрирует, что эти поля пусты, если они инициализированы в методе @PostConstruct, а не инициализируются в конструкторе класса.   -  person Luiggi Mendoza    schedule 07.12.2013


Ответы (1)


Как же тогда они могут быть инициализированы в конструкторе, небольшая путаница? (Я знаю, что конструктор вызывается до вызова метода, аннотированного @PostConstruct).

Используйте метод init @PostConstruct только для инициализации полей, которые вводятся (например, Ejbs). Если у вас нет никаких инъекций и зависимостей, метод init становится бесполезным. Конструктор bean-компонента используется для инициализации собственных свойств bean-компонента. В вашем примере у вас нет инъекции, поэтому вы можете безопасно удалить этот метод @PostConstruct init.

Если эти поля инициализируются в методе, аннотированном @PostConstruct, то есть init (), в этом случае (вместо их инициализации в конструкторе, как показано во фрагменте) их указанные значения не установлены, если и пока пользователь не войдет в систему (если сеанс не создан).

Это нормальное поведение, нет причин подчеркивать не, потому что компонент @SessionScoped создается и инициализируется только при создании нового сеанса.

Для получения дополнительной информации проверьте ссылку, на вопрос уже дан ответ: Зачем использовать @PostConstruct?

person Community    schedule 06.12.2013
comment
Обратите внимание, что только один @SessionScoped bean-компонент может быть создан за сеанс только в том случае, если вы создаете его вручную или ссылаетесь на него из представления. На самом деле он не создается автоматически при начале сеанса. Ваше утверждение is created and initialized only when a new session is created может быть воспринято как неправильное. - person Xtreme Biker; 07.12.2013
comment
После того, как определенные изменения были внесены спустя много времени после этого сообщения, проблема, указанная в теле вопроса, не может быть воспроизведена. Поэтому я не уверен в точной первопричине проблемы. Возможно, виноваты были некоторые запросы AJAX. Спасибо. - person Tiny; 16.05.2014