У меня есть проект, использующий 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>
ViewScope
сломана и превращается в@NoneScoped
(что хуже, чем@RequestScoped
). Где вы взяли кастомную реализацию? - person Luiggi Mendoza   schedule 05.11.2013porting viewscope
отJSF
доSpring
, но не работал должным образом. Не уверен, что это именно тот способ реализации, но, поскольку он исходил от основателяprimefaces
, он должен работать правильно. Проверьте мой ответ в этом посте, полезен ли он для вас stackoverflow.com/questions/13005421/. Я использовалnative JSF viewscope
сserialization methods
, чтобы вернуть spring bean, который становится нулевым во времяSerialization
- person SRy   schedule 05.11.2013configureBean
используйтеautowireBean
. Первый также вызывает все методы обратного вызова (например,@PostConstruct
аннотированные методы), тогда как последний применяет только автоматическое связывание. - person M. Deinum   schedule 05.11.2013