@PostConstruct вызывается несколько раз с настраиваемой областью просмотра

У меня есть проект, использующий JSF 2.0, mojarra 2.2.4, Tomcat 7 и Primefaces 3.5. Мы также используем Spring и Hibernate.

Я столкнулся с проблемой, связанной с аннотированным методом @PostContruct. Он должен вызываться только один раз при создании страницы, а вместо этого вызывается более 10 раз. Он также вызывается, когда я нажимаю <p:commandButton/>. Множественные вызовы не происходят с компонентами SessionScoped, только с моими пользовательскими компонентами ViewScoped.

Это реализация Custom ViewScope:

ViewScope

public class ViewScope implements Scope {

@Override
@SuppressWarnings("rawtypes")
public Object get(String name, ObjectFactory objectFactory) {       
    if (FacesContext.getCurrentInstance().getViewRoot() != null) {
        Map<String, Object> viewMap = FacesContext.getCurrentInstance()
            .getViewRoot().getViewMap();

        if (viewMap.containsKey(name)) {                
            Object bean = viewMap.get(name);

            // restore a transient autowired beans after re-serialization bean
            WebApplicationContext webAppContext = ContextLoader.getCurrentWebApplicationContext();
            AutowireCapableBeanFactory autowireFactory = webAppContext.getAutowireCapableBeanFactory();
            if (webAppContext.containsBean(name)) {                 
                // Reconfigure restored bean instance.
                bean = autowireFactory.configureBean(bean, name);
            }
            // end restore

        return bean;
        } else {
            Object object = objectFactory.getObject();
            viewMap.put(name, object);
            return object;
        }
    }else{
        return null;
    }   
}

@Override
public Object remove(String name) {

    return FacesContext.getCurrentInstance().getViewRoot().getViewMap()
            .remove(name);
}

public String getConversationId() {
    return null;
}

@Override
public void registerDestructionCallback(String name, Runnable callback) {
}

public Object resolveContextualObject(String key) {
    return null;
}

 public void clearBean() { FacesContext.getCurrentInstance()
        .getViewRoot().getViewMap().clear();
}

}

Боб

@SuppressWarnings("serial")
@Component("grupoFormBean")
@Scope("view")
public class GrupoFormBean implements Serializable {
Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());

@PostConstruct
public void init(){
    System.out.println("=========== entering PostConstruct =============");
    this.comboSistema = sistemaService.findAll();
    System.out.println("=========== leaving PostConstruct =============");
}   

public void prepara(){
    if(!FacesContext.getCurrentInstance().isPostback()){
        if(grupoId==null){              
            return;
        }else{              
            this.alterar = true;
            setGrupo(grupoService.findById(grupoId));
            prepareAlterar();               
        }
    }
}
//implementation of others components
//getters and setters

}

XHTML-страница

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <ui:composition template="../WEB-INF/templates/page.xhtml"
      xmlns="http://www.w3.org/1999/xhtml"      
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

    <ui:define name="content">

    <f:metadata>
    <f:viewParam name="idgrupo" id="idgrupo" value="#{grupoFormBean.grupoId}"/>
        <f:event type="preRenderView" listener="#{grupoFormBean.prepara}">
        </f:event>
    </f:metadata>

        <div class="titulo-pagina">

            <h2>Cadastro de Grupo</h2>

        </div>

        <h:form id="formulario" styleClass="formularios">

    //... page stuff

    </h:form>

    </ui:define>
</ui:composition>

Это журнал, когда я впервые захожу на страницу:

=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as    SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as     SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============
=========== entering PostConstruct =============
Hibernate: select sistema0_.ID as ID3_, sistema0_.NOME as NOME3_, sistema0_.SIGLA as SIGLA3_, sistema0_.VERSAOATUAL as VERSAOAT4_3_ from SCA.SISTEMA sistema0_ order by sistema0_.NOME
=========== leaving PostConstruct =============

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <!-- View scope -->
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="view">
                <bean class="mypackage.util.ViewScope"/>
            </entry>
        </map>
    </property>
</bean>

</beans>

person Anika    schedule 05.11.2013    source источник
comment
Единственное, в чем мы уверены, так это в том, что ваша собственная реализация ViewScope сломана и превращается в @NoneScoped (что хуже, чем @RequestScoped). Где вы взяли кастомную реализацию?   -  person Luiggi Mendoza    schedule 05.11.2013
comment
Он пришел с базовым проектом, который я должен был использовать в качестве эталона.   -  person Anika    schedule 05.11.2013
comment
Вы уверены, что правильно настроили новую настраиваемую область?   -  person Luiggi Mendoza    schedule 05.11.2013
comment
да. Мне просто понравилось здесь docs.spring.io/spring/docs/3.0.0.RC2/spring-framework-reference/ На всякий случай выложу конфигурацию...   -  person Anika    schedule 05.11.2013
comment
Я пытался реализовать porting viewscope от JSF до Spring, но не работал должным образом. Не уверен, что это именно тот способ реализации, но, поскольку он исходил от основателя primefaces, он должен работать правильно. Проверьте мой ответ в этом посте, полезен ли он для вас stackoverflow.com/questions/13005421/. Я использовал native JSF viewscope с serialization methods, чтобы вернуть spring bean, который становится нулевым во время Serialization   -  person SRy    schedule 05.11.2013
comment
Вместо configureBean используйте autowireBean. Первый также вызывает все методы обратного вызова (например, @PostConstruct аннотированные методы), тогда как последний применяет только автоматическое связывание.   -  person M. Deinum    schedule 05.11.2013
comment
@M.DeinumM.Deinum Отлично сработало, спасибо!   -  person Anika    schedule 06.11.2013