无法在复合组件上使用不同的CDI ViewScoped bean实例

时间:2015-03-06 19:32:21

标签: jsf-2 cdi managed-bean composite-component

我工作的项目有一个共同的行为,即用户在使用任何系统功能之前必须选择一个或多个存储。

创建了一个复合组件,以满足负责业务规则的独特位置的要求。

最近我收到了修复问题的请求:当dev在受管Bean上使用了两次(或更多)组件时,它们共享同一个实例。

E.g:

@Named
@ViewScoped
public class MovVolumeManager implements Serializable {

@Inject
private SeletorLocalizacaoManager seletorLocalOrigem; 

@Inject
private SeletorLocalizacaoManager seletorLocalOrigem; 

在我的测试中,seletorLocalOrigem和seletorLocalOrigem将保持相同的值。

据我所知,当CDI发现同一个类被声明为两个不同的变量时,它们会在容器内存上共享相同的地址。我是CDI的新手,我不知道如何解决这个问题。

预期的行为是:bean可以有N" Seletor Local"在同一页上。

当有人想要使用" Seletor Local"时,他应该:

  • 在Bean上注入组件并在后期构建阶段初始化

    @Named
    @ViewScoped
    public class MovVolumeOrigemManager implements Serializable {
    
    @Inject
    @Getter @Setter
    private SeletorLocalizacaoManager seletorLocal;    
    
    @PostConstruct
    public void inicializar() {
        seletorLocal.setSelecaoMultipla(true);
        seletorLocal.setCodigosClasseExibicao(BeanUtil.adicionarClassesLocais());
        seletorLocal.setCodigosClasseSelecao(BeanUtil.adicionarClassesLocais());
        seletorLocal.setGruposSegurancaWeb(BeanUtil.adicionarGruposSeguranca());
        seletorLocal.setRealizaAcaoAdicionalAposSelecao(false);
        seletorLocal.criarArvoreHierarquica();      
        }
    }
    
  • 在标记

    上传递必需的属性
    <sup:seletorLocalizacao id="seletorLocalizacaoDestino" mb="#{movVolumeDestinoBean.seletorLocal}" minQueryLength="2" />
    

环境

  • WebSphere Application Server 8.5.5.2
  • Apache MyFaces 2.0.2
  • PrimeFaces 5.0

SeletorLocalizacao经理类

@Named
@ViewScoped
public class SeletorLocalizacaoManager implements Serializable {

    private static final long serialVersionUID = -4705289709340063089L;

    @Inject
    private LocalizacaoRN localizacaoRN;

    @Inject
    private ArvoreUtil arvoreUtil;

    private MetodoSelecaoLocalEnum controleExibicao;
    private Boolean renderHierarquia;
    private Boolean renderIncremental;
    private boolean selecaoMultipla;

    private String labelClasseLocal;

    private boolean semRestricaoSelecao;

    private List<ClasseLocalTO> codigosClasseExibicao;

    private List<String> gruposSegurancaWeb;

    private List<ClasseLocalTO> codigosClasseSelecao;

    private List<LocalizacaoTO> locaisHierarquicosSelecionados;

    private List<LocalizacaoTO> locaisClasseSelecionados;

    private List<LocalizacaoTO> locaisSelecionados;

    private List<LocalizacaoTO> historicoLocaisSelecionados;

    private LocalizacaoTO localSelecionado;

    private TreeNode localSelecionadoAnterior;

    private TreeNode arvoreHierarquica;

    private List<LocalizacaoTO> listaLocalClasseCadastrados;
    private List<LocalizacaoTO> listaLocalCadastrados;

    private NodeSelectEvent tbLocalNode;

    private boolean realizaAcaoAdicionalAposSelecao;

    @PostConstruct
    public void init()  {
        if (controleExibicao == null) {
            controleExibicao = MetodoSelecaoLocalEnum.HIERARQUICO;
        }

        controlarExibicao(controleExibicao);
    }

    public void criarArvoreHierarquica(){
        arvoreHierarquica = arvoreUtil.montarArvoreLocalizacao(this.buscarHierarquia(),true);
    }

    public void alternarExibicao() {
        controlarExibicao(controleExibicao);

    }

    public void alternarExibicao(AjaxBehaviorEvent event) {
        controlarExibicao(controleExibicao);

    }

    public void controlarExibicao(MetodoSelecaoLocalEnum parametro) {
        if (parametro == MetodoSelecaoLocalEnum.HIERARQUICO) { 
            setRenderHierarquia(true);
            setRenderIncremental(false);
        } else {
            if(parametro == MetodoSelecaoLocalEnum.INCREMENTAL)
            setRenderHierarquia(false);
            setRenderIncremental(true);
        }
    }

    public String gerarLabelClasse(boolean separador)   {
        StringBuilder labelClasse = new StringBuilder();

        for(int i=0; i< codigosClasseSelecao.size(); i++)   {
            labelClasse.append(codigosClasseSelecao.get(i).getDescricaoClasseLocal());

            if(i !=codigosClasseSelecao.size() -1)  {
                labelClasse.append("/");
            }
        }
        if(separador)   {
            labelClasse.append("");
        }
        return labelClasse.toString();
    }

    public void selecionarLocalHierarquico()    {
        if(null == locaisHierarquicosSelecionados)  {
            locaisHierarquicosSelecionados = new ArrayList<LocalizacaoTO>();
        }

        if(localSelecionado != null)    {
            this.verificaRestricaoSelecao(localSelecionado);
            if(semRestricaoSelecao) {
                if(!selecaoMultipla){
                    locaisHierarquicosSelecionados.clear();
                }
                locaisHierarquicosSelecionados.add(localSelecionado);
                localSelecionado = null;
                RequestContext.getCurrentInstance().execute("PF('dlgSelecaoHierarquica').hide();");
            } else {
                MessageFormat msgFormat = new MessageFormat("A localização {0} não é uma classe de local autorizada. Favor selecionar um local da classe {1}.");
                Object[] args = {localSelecionado.getDsLocalizacao(), gerarLabelClasse(false)};

                String msg = msgFormat.format(args);

                FacesContext.getCurrentInstance().addMessage("GROWL", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro", msg));
                RequestContext.getCurrentInstance().update("mensagens");
            }
        }
    }

    public void onNodeSelect(NodeSelectEvent event) {  
        LocalizacaoTO local = null;

        try {

            if ( ! event.equals(tbLocalNode) ) {
                if (tbLocalNode != null) {
                    tbLocalNode.getTreeNode().setSelected(false);  
                }

                tbLocalNode = event;
            }

            local = ((LocalizacaoTO) event.getTreeNode().getData());
            event.getTreeNode().setSelected(true);

            if(null == localSelecionado)    {
                localSelecionado = new LocalizacaoTO();
                historicoLocaisSelecionados = new ArrayList<LocalizacaoTO>();
            }

            localSelecionado = local;
            historicoLocaisSelecionados.add(local);

            if(localSelecionadoAnterior != null)    {
                localSelecionadoAnterior.setSelected(false);
                localSelecionadoAnterior.setExpanded(false);
            }

            this.adicionarNiveisInferiores(local, event);

            localSelecionadoAnterior = event.getTreeNode();
        } catch (Exception e)   {
        }
    }

    private void adicionarNiveisInferiores(LocalizacaoTO local, NodeSelectEvent event)  {
        if(local.getNiveis() > 0 && event.getTreeNode().getChildCount() == 0)   {
            List<LocalizacaoTO> niveisInferiores = this.buscarHierarquia(local.getIdLocalizacao());

            if(niveisInferiores != null && niveisInferiores.size() > 0) {
                for(LocalizacaoTO localizacao : niveisInferiores)   {
                    new DefaultTreeNode(localizacao, event.getTreeNode());
                }   
                event.getTreeNode().setExpanded(true);
            }               
        }
    }

    public void verificaRestricaoSelecao(LocalizacaoTO local)   {
        Long possuiClasseLocal = 0L;

        if(null == codigosClasseSelecao || codigosClasseSelecao.size() == 0)    {
            semRestricaoSelecao = true;
        } else {
            for(ClasseLocalTO classeLocal : codigosClasseSelecao)   {
                if(classeLocal.getCodClasseLocal().equals(local.getCdClasseLocal()))    {
                    possuiClasseLocal++;
                }
            }

            if(possuiClasseLocal > 0)   {
                semRestricaoSelecao = true;
            } else {
                semRestricaoSelecao = false;
            }
        }
    }

    public List<LocalizacaoTO> buscarHierarquia()   {
        return localizacaoRN.buscarHieraquia(codigosClasseExibicao, null, gruposSegurancaWeb);
    }

    public List<LocalizacaoTO> buscarHierarquia(Long idLocalSuperior)   {
        return localizacaoRN.buscarHieraquia(codigosClasseSelecao, idLocalSuperior, gruposSegurancaWeb);
    }

    public List<LocalizacaoTO> completarClasseLocalizacao(String query) {
        if (listaLocalClasseCadastrados == null || listaLocalClasseCadastrados.size() == 0) {
            setListaLocalClasseCadastrados(new ArrayList<LocalizacaoTO>());
        }

        List<LocalizacaoTO> sugestoes = new ArrayList<LocalizacaoTO>();
        sugestoes = localizacaoRN.buscarRegistrosAutocomplete(this.getCodigosClasseExibicao(), query.toUpperCase() + "%", null, gruposSegurancaWeb);

        for (LocalizacaoTO localizacaoTO : sugestoes) {
            getListaLocalClasseCadastrados().add(localizacaoTO);
        }

        return sugestoes;
    }

    public List<LocalizacaoTO> completarLocais(String query)    {
        if (listaLocalCadastrados == null || listaLocalCadastrados.size() == 0) {
            setListaLocalCadastrados(new ArrayList<LocalizacaoTO>());
        }

        List<LocalizacaoTO> sugestoes = new ArrayList<LocalizacaoTO>();

        sugestoes = localizacaoRN.buscarRegistrosAutocomplete(this.getCodigosClasseSelecao(), query.toUpperCase() + "%", locaisClasseSelecionados,gruposSegurancaWeb);

        for (LocalizacaoTO localizacaoTO : sugestoes) {
            getListaLocalCadastrados().add(localizacaoTO);
        }

        return sugestoes;
    }


    public void handleSelectClasseLocalizacao(SelectEvent event)    {
        LocalizacaoTO localRecebido = (LocalizacaoTO)event.getObject();
        if(selecaoMultipla == false)    {
            if (locaisClasseSelecionados != null && locaisClasseSelecionados.size() > 0) {
                locaisClasseSelecionados.clear();
                locaisClasseSelecionados.add(localRecebido);

            }
            if (locaisSelecionados != null && locaisSelecionados.size() > 0) {
                locaisSelecionados.clear();
            }
        }
    }

    public void handleUnSelectHierarquico(UnselectEvent event)  {   
        LocalizacaoTO objetoRemovido = (LocalizacaoTO)event.getObject();
    }   


    public void handleUnSelectClasseLocalizacao(UnselectEvent event)    {
        if (locaisSelecionados != null && locaisSelecionados.size() > 0) {
            locaisSelecionados.clear();
        }
    }

    public void handleSelectLocalizacao(SelectEvent event)  {
        LocalizacaoTO localRecebido = (LocalizacaoTO)event.getObject();
        if(selecaoMultipla == false)    {
            if (locaisSelecionados != null && locaisSelecionados.size() > 0) {
                locaisSelecionados.clear();
                locaisSelecionados.add(localRecebido);
            }
        }
    }

}

SeletorLocalizacao复合组件

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:o="http://omnifaces.org/ui"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:su="http://java.sun.com/jsf/composite/selecao">

<cc:interface>
    <cc:attribute name="id" required="true" />
    <cc:attribute name="mb" required="true" type="br.com.usiminas.ipce.mb.SeletorLocalizacaoMB" />
    <cc:attribute name="form" default="formPrincipal" />
    <cc:attribute name="updateClasseLocalizacao" default="@this" />
    <cc:attribute name="updateLocalizacao" default="@this" />
    <cc:attribute name="updateItemSelectHierarquico"/>
    <cc:attribute name="updateItemSelectIncremental"/>
    <cc:attribute name="queryDelay" default="1000"/>
    <cc:attribute name="minQueryLength" default="3" />
    <cc:attribute name="bloqueiaModal" default="true" />
    <cc:attribute name="nomeAcaoAdicional" />
    <cc:attribute name="metodoAcaoAdicional" method-signature="void complementarSelecaoLocal()"/>
    <cc:attribute name="updateAcaoAdicional" />
</cc:interface>

<cc:implementation>
    <p:remoteCommand id="#{cc.attrs.id}BotaoRemoto" 
                     name="complementar" 
                     action="#{cc.attrs.metodoAcaoAdicional}"
                     update="#{cc.attrs.updateAcaoAdicional}"
                     async="true"/>

    <h:outputText value="Seleção de local" styleClass="tituloFiltro"/>

    <h:panelGrid columns="2">
        <p:selectOneRadio id="#{cc.attrs.id}Radio" value="#{cc.attrs.mb.controleExibicao}" >
            <p:ajax event="valueChange" listener="#{cc.attrs.mb.alternarExibicao}" update="#{cc.attrs.id}Conteiner" oncomplete="bloqueiaAutoMulti()"/>
            <f:selectItem itemLabel="Hierarquica" itemValue="HIERARQUICO" />
            <f:selectItem itemLabel="Incremental" itemValue="INCREMENTAL" />
        </p:selectOneRadio>
    </h:panelGrid>

    <p:panelGrid id="#{cc.attrs.id}Conteiner" columns="1" styleClass="ui-custompanelgrid">
    <h:panelGrid id="#{cc.attrs.id}GrdHierarquico" columns="1" rendered="#{cc.attrs.mb.renderHierarquia}">
        <p:outputLabel value="#{cc.attrs.mb.labelClasseLocal}" />
        <h:panelGrid columns="2">
            <p:autoComplete id="#{cc.attrs.id}ACHierarquico"
                scrollHeight="200" scrollable="true" styleClass="ui-autocomp ui-automulti-readonly #{cc.attrs.id}-auto-complete"
                var="local" itemValue="#{local}" itemLabel="#{local.cdLocalCompleto}"
                value="#{cc.attrs.mb.locaisHierarquicosSelecionados}"
                multiple="true" converter="#{localizacaoTOHierarquicoConverter}"
                minQueryLength="10"
                >
                <p:ajax event="itemUnselect"
                    update="@this" 
                    listener="#{cc.attrs.mb.handleUnSelectHierarquico}"
                    oncomplete="bloqueiaAutoMulti()"/>
            </p:autoComplete>

            <p:commandLink id="#{cc.attrs.id}BtTreeHierarquia" 
                           title="Abrir árvore"
                           global="false"
                           onclick="PF('dlgSelecaoHierarquica').show();">
                <h:graphicImage style="cursor: pointer; width: 20px;"
                                title="Abrir Árvore"
                                library="imagens" 
                                name="hierarchy.svg" />
            </p:commandLink>
        </h:panelGrid>
    </h:panelGrid>

    <h:panelGrid id="#{cc.attrs.id}GrdIncremental" columns="1" rendered="#{cc.attrs.mb.renderIncremental}">

        <p:outputLabel value="#{cc.attrs.mb.labelClasseLocal}" />
        <p:autoComplete value="#{cc.attrs.mb.locaisClasseSelecionados}" 
                        scrollHeight="200"
                        scrollable="true" 
                        multiple="true"
                        styleClass="ui-autocomp" 
                        id="#{cc.attrs.id}ACPreFiltro" var="local"
                        completeMethod="#{cc.attrs.mb.completarClasseLocalizacao}"
                        itemLabel="#{local.cdLocalCompleto}"
                        itemValue="#{local}" 
                        minQueryLength="#{cc.attrs.minQueryLength}"
                        converter="#{localizacaoTOPreFiltroConverter}"
                        emptyMessage="Não existem dados para apresentar."
                        queryDelay="#{cc.attrs.queryDelay}"
                        forceSelection="true"
                        >
            <p:ajax event="itemSelect"
                    listener="#{cc.attrs.mb.handleSelectClasseLocalizacao}"
                    update="@parent" />
            <p:ajax event="itemUnselect"
                    update="@parent" 
                    listener="#{cc.attrs.mb.handleUnSelectClasseLocalizacao}"/>

            <f:facet name="itemtip">
                <h:panelGrid columns="2" cellpadding="5" styleClass="itemTips">
                    <f:facet name="header">
                        <h:outputText value="Hierarquia " />
                        <br />
                        <h:outputText value="#{local.hierarquia}" />
                    </f:facet>
                </h:panelGrid>
            </f:facet>

        </p:autoComplete>

        <p:autoComplete id="#{cc.attrs.id}ACFiltro" scrollHeight="200"
            scrollable="true" styleClass="ui-autocomp" var="local"
            itemValue="#{local}" itemLabel="#{local.cdLocalCompleto}"
            value="#{cc.attrs.mb.locaisSelecionados}" multiple="true"
            minQueryLength="#{cc.attrs.minQueryLength}"
            queryDelay="#{cc.attrs.queryDelay}"
            completeMethod="#{cc.attrs.mb.completarLocais}"
            converter="#{localizacaoTOFiltroConverter}"
            emptyMessage="Não existem dados para apresentar."
            forceSelection="true">
            <c:choose>
                <c:when test="#{cc.attrs.mb.realizaAcaoAdicionalAposSelecao}">
                    <p:ajax event="itemSelect"
                        listener="#{cc.attrs.mb.handleSelectLocalizacao}"
                        update="@this" 
                        oncomplete="complementar();" />
                </c:when>
                <c:otherwise>
                    <p:ajax event="itemSelect"
                        listener="#{cc.attrs.mb.handleSelectLocalizacao}"
                        update="@this" />
                </c:otherwise>
            </c:choose>

            <f:facet name="itemtip">
                <h:panelGrid columns="2" cellpadding="5" styleClass="itemTips">
                    <f:facet name="header">
                        <h:outputText value="Hierarquia" />
                        <br />
                        <h:outputText value="#{local.hierarquia}" />
                    </f:facet>
                </h:panelGrid>
            </f:facet>
        </p:autoComplete>
    </h:panelGrid>
</p:panelGrid>

    <p:dialog header="Busca Hierarquica"
          id="#{cc.attrs.id}ModalTree"
          widgetVar="dlgSelecaoHierarquica" 
          showEffect="fade" 
          hideEffect="fade" 
          closeOnEscape="true"
          modal="#{cc.attrs.bloqueiaModal}"
          height="400px"
          width="500px">
        <h:panelGrid columns="2">
            <c:choose>
                <c:when test="#{cc.attrs.mb.realizaAcaoAdicionalAposSelecao}">
                    <p:commandButton id="#{cc.attrs.id}btnSelecao" value="Selecionar e Voltar" action="#{cc.attrs.mb.selecionarLocalHierarquico}" 
                                                                   update="@(.#{cc.attrs.id}-auto-complete)" 
                                                                   onsuccess="bloqueiaAutoMulti();"
                                                                   oncomplete="complementar();"/>
                </c:when>
                <c:otherwise>
                    <p:commandButton id="#{cc.attrs.id}btnSelecao" value="Selecionar e Voltar" action="#{cc.attrs.mb.selecionarLocalHierarquico}" 
                                    update="@(.#{cc.attrs.id}-auto-complete)" oncomplete="bloqueiaAutoMulti();"/>
                </c:otherwise>
            </c:choose>
            <p:commandButton value="Voltar" type="button" onclick="PF('dlgSelecaoHierarquica').hide();" />
        </h:panelGrid>

        <p:scrollPanel style="width:100%;height:350;" mode="native">
            <p:tree id="#{cc.attrs.id}Tree"
                    style="width:100%;height:100%;" 
                    styleClass="estilo-arvore"
                    value="#{cc.attrs.mb.arvoreHierarquica}" 
                    var="local" 
                    selectionMode="multiple" 
                    dynamic="true" 
                    animate="true">
                <p:ajax event="select" listener="#{cc.attrs.mb.onNodeSelect}" update="@this"/>  
                    <p:treeNode >
                        <h:outputText value="#{local.cdClasseLocal}: #{local.cdLocalizacao} (#{local.niveis})" />
                    </p:treeNode>
            </p:tree>
        </p:scrollPanel>
    </p:dialog>
    <script>
        bloqueiaAutoMulti();
    </script>
</cc:implementation>

</html>

0 个答案:

没有答案