2

我目前正在查看代码并发现 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>                    

我目前正在与一位同事讨论哪种范围最适合转换器...

从 JSF 页面引用的 95% 的管理器 bean 是@ViewScoped,所以我认为最好让转换器@ViewScoped也是如此(而不是 @RequestScoped,据我所知,它会为每个 AJAX 请求重新创建一个转换器实例)。

然后我的同事补充说,转换器可能应该是这样@Dependent,因为这会自动将转换器放入周围 bean 所在的范围内。我的感觉是,这行不通。但是,我真的不能不同意,因为我的知识几乎到此为止。

那么,当几乎所有从 JSF 引用的 bean 都是 时,转换器的最佳范围可能@ViewScoped是什么?

PS:注意我们使用Seam 3来混合@Named@ViewScoped

4

1 回答 1

3

由于大多数转换器实际上是无状态的,因此它们很容易成为@ApplicationScoped,在我看来,这是它们最自然的范围。尽管如此,有些转换器实际上并非如此。例如,DateTimeConverter后面的<f:convertDateTime>标签确实持有一些状态。此外,默认实现@FacesConverter使用Application#createConverter(String converterId)在需要时创建新的转换器实例,因此每个请求可以多次创建它。

此外,就我而言,就范围而言,自定义转换器与引用的支持 bean 没有任何交集,因此它们是否无关紧要ViewScoped。在选择转换器范围时,真正重要的是转换器实例中保存的状态范围,正如 BalusC 正确发现的那样。

至于您问题中的转换器实际上是无状态的,它可以是安全的@ApplicationScoped

于 2013-04-11T18:48:24.090 回答