Область конвертера JSF при использовании CDI (Seam 3) с областью просмотра

В настоящее время я просматриваю код и нашел преобразователи CDI, такие как:

@Named
@RequestScoped
public class BankConverter implements Converter, Serializable
{
    @EJB
    private BankService bankService;

    @Override
    public Object getAsObject( FacesContext ctx, UIComponent comp, String identifier )
    {
        if ( identifier == null || identifier.trim().isEmpty() )
        {
            return null;
        }

        Bank bank = null;

        try
        {       
            bank = this.bankService.findByPrimaryKey( Long.valueOf( identifier ) );
        }
        catch( Exception e )
        {
            // omitted
        }

        return bank;
    }

    @Override
    public String getAsString( FacesContext ctx, UIComponent comp, Object obj )
    {
        if ( obj == null || ( ( Bank ) obj ).getId() == null )
        {
            return null;
        }

        return ( ( Bank ) obj ).getId().toString();
    }

}

Преобразователи в основном всегда используются так (обратите внимание на converter="#{bankConverter}"):

<p:autoComplete id="bank"
                value="#{employeeDepotManager.selectedBank}"
                var="bnk"
                converter="#{bankConverter}"
                completeMethod="#{autoCompleter.completeBankSearch}"
                itemLabel="#{bnk.name}"
                itemValue="#{bnk}"
                forceSelection="false"
                minQueryLength="3"
                global="true"
                validator="#{employeeDepotManager.validateBank}"
                scrollHeight="200">
    <p:ajax event="itemSelect" update="bank-code bank-name" />
    <p:column>#{bnk.code}</p:column>
    <p:column>#{bnk.name}</p:column>
</p:autoComplete>                    

В настоящее время я обсуждаю с коллегой, какая область будет лучше для конвертеров...

95% bean-компонентов менеджера, на которые ссылаются страницы JSF, имеют @ViewScoped, и поэтому я подумал, что было бы лучше, чтобы преобразователи также были @ViewScoped (вместо @RequestScoped, который, насколько я понимаю, воссоздает экземпляр преобразователя для каждого запроса AJAX) .

Затем мой коллега добавил, что преобразователь, вероятно, должен быть @Dependent, так как это автоматически поместит преобразователи в область, в которой находятся окружающие компоненты. Я чувствовал, что это не сработает. Тем не менее, я не мог не согласиться, поскольку мои знания в значительной степени заканчиваются здесь.

Итак, что вероятно было бы наилучшей областью действия для преобразователей, когда почти все bean-компоненты, на которые ссылается JSF, являются @ViewScoped?

PS: обратите внимание, что мы используем шов 3, чтобы смешать @Named и @ViewScoped.


person Kawu    schedule 11.04.2013    source источник


Ответы (1)


Поскольку большая часть преобразователей на самом деле не имеют состояния, они легко могут быть @ApplicationScoped, что, на мой взгляд, является для них наиболее естественной областью применения. Тем не менее, некоторые конвертеры на самом деле таковыми не являются. Например, DateTimeConverter за тегом <f:convertDateTime> действительно содержит некоторое состояние. Кроме того, реализация @FacesConverter по умолчанию использует Application#createConverter(String converterId), который создает новый экземпляр преобразователя, когда это необходимо, поэтому его можно создать более одного раза для каждого запроса.

Кроме того, насколько я понимаю, пользовательские преобразователи не имеют никакого пересечения с указанными вспомогательными компонентами с точки зрения области действия, поэтому не имеет значения, являются ли они ViewScoped или нет. Что на самом деле имеет значение при выборе области действия преобразователя, так это область действия состояния, хранящегося в экземпляре преобразователя, как это правильно заметил BalusC.

Поскольку конвертер в вашем вопросе на самом деле не имеет состояния, он может смело быть @ApplicationScoped.

person skuntsel    schedule 11.04.2013
comment
Обратите внимание, что не все преобразователи не имеют состояния. Например. DateTimeConverter за <f:convertDateTime> нет. Однако конкретный в вопросе есть, так что это действительно может быть @ApplicationScoped. Таким образом, ответ в конечном итоге сводится к следующему: зависит от области действия состояния как удержания в экземпляре преобразователя. - person BalusC; 11.04.2013
comment
@BalusC Спасибо за умную поправку. DateTimeConverter действительно не является лицом без гражданства, поэтому мой ответ на самом деле логически неверен. Вы не возражаете, что я включил ваши расследования в ответ? - person skuntsel; 12.04.2013
comment
Скунцель, не стесняйтесь исправить свой ответ. Каву, что касается моего блога, это было просто на всякий случай, вы никогда не знаете, когда начинается копипастинг. Например. UserService может в их случае иметь состояние. По крайней мере, я обновил пример блога с комментарием позади @RequestScoped. - person BalusC; 12.04.2013
comment
Здесь идет большая дискуссия. Я не хочу бросать гаечный ключ, но мы больше не активно разрабатываем Seam 3, и, к сожалению, Apache DeltaSpike еще не совсем готов, он все еще достоин производства, просто в нем нет всего материала JSF. там еще. Не стесняйтесь продолжать использовать Seam 3, но вам придется обеспечивать себя самостоятельно. - person LightGuard; 13.04.2013
comment
@BalusC, рискуя показаться глупым, я думаю, что в вашем блоге на странице, упомянутой выше, есть ошибка. при преобразовании и проверке параметров запроса GET в функции вы используете modelValue, а затем значение, которое нигде не определено. if (modelValue instanceof User) { return String.valueOf(((User) value).getId()); } - person Ced; 23.10.2015
comment
@Ced: опечатка исправлена. Спасибо. - person BalusC; 23.10.2015