Scope JSF View in spring

Esiste un ambito come JSF @ViewScoped in Spring 3.0? Ho un’applicazione che usa JSF + Spring dove i bean di supporto sono gestiti da Spring. In spring non ho trovato alcun ambito come l’ambito wiew di JSF. Ho visto il blog Porting JSF 2.0 ViewScope a Spring 3.0 , ma non ha funzionato per me.

Ecco il mio tentativo sull’ambito personalizzato Spring:

 import java.util.Map; import javax.faces.context.FacesContext; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.config.Scope; /** * Implements the JSF View Scope for use by Spring. This class is registered as a Spring bean with the CustomScopeConfigurer. */ public class ViewScope implements Scope { public Object get(String name, ObjectFactory objectFactory) { System.out.println("**************************************************"); System.out.println("-------------------- Getting objects For View Scope ----------"); System.out.println("**************************************************"); if (FacesContext.getCurrentInstance().getViewRoot() != null) { Map viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap(); if (viewMap.containsKey(name)) { return viewMap.get(name); } else { Object object = objectFactory.getObject(); viewMap.put(name, object); return object; } } else { return null; } } public Object remove(String name) { System.out.println("**************************************************"); System.out.println("-------------------- View Scope object Removed ----------"); System.out.println("**************************************************"); if (FacesContext.getCurrentInstance().getViewRoot() != null) { return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name); } else { return null; } } public void registerDestructionCallback(String name, Runnable callback) { // Do nothing } public Object resolveContextualObject(String key) { return null; } public String getConversationId() { return null; } } 

application-context.xml :

          

Recentemente ho creato un artefatto maven che risolverà questo problema.

Vedi il mio github javaplugs / spring-jsf repository.

Ho fatto qualcosa di simile senza Porting bean to Spring. Funziona per me.

 @ManagedBean(name="bean") @ViewScoped // actual jsf viewscoped only with javax.faces.viewscoped import public class Bean implements Serializable { @ManagedProperty(value="#{appService}") // Spring Manged Bean and singleton private transient AppService appService; // Getting AppService Object which is singleton in the application during deserialization private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); FacesContext context = FacesContext.getCurrentInstance(); appService = (AppService)context.getApplication() .evaluateExpressionGet(context, "#{appService}", AppService.class); } } 
 public class ViewScopeCallbackRegistrer implements ViewMapListener { @SuppressWarnings("unchecked") @Override public void processEvent(SystemEvent event) throws AbortProcessingException { if (event instanceof PostConstructViewMapEvent) { PostConstructViewMapEvent viewMapEvent = (PostConstructViewMapEvent) event; UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent(); viewRoot.getViewMap().put(ViewScope.VIEW_SCOPE_CALLBACKS, new HashMap()); } else if (event instanceof PreDestroyViewMapEvent) { PreDestroyViewMapEvent viewMapEvent = (PreDestroyViewMapEvent) event; UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent(); Map callbacks = (Map) viewRoot .getViewMap().get(ViewScope.VIEW_SCOPE_CALLBACKS); if (callbacks != null) { for (Runnable c : callbacks.values()) { c.run(); } callbacks.clear(); } } } @Override public boolean isListenerForSource(Object source) { return source instanceof UIViewRoot; } } 
 public class ViewScope implements Scope { public static final String VIEW_SCOPE_CALLBACKS = "viewScope.callbacks"; @Override public synchronized Object get(String name, ObjectFactory objectFactory) { Object instance = this.getViewMap().get(name); if(instance == null){ instance = objectFactory.getObject(); this.getViewMap().put(name, instance); } return instance; } @SuppressWarnings("unchecked") @Override public Object remove(String name) { Object instance = this.getViewMap().remove(name); if(instance == null){ Map callbacks = (Map) this.getViewMap().get(VIEW_SCOPE_CALLBACKS); if(callbacks != null) callbacks.remove(name); } return instance; } /** * Responsável por registrar uma chamada de destruição ao bean * que será armazenadano [b]viewMap[/b] da [b]ViewRoot[/b](nossa página que será mostrada) * @see #getViewMap() * @param name - nome do bean * @param runnable */ @SuppressWarnings("unchecked") @Override public void registerDestructionCallback(String name, Runnable runnable) { Map callbacks = (Map) this.getViewMap().get(VIEW_SCOPE_CALLBACKS); if(callbacks != null) callbacks.put(name, runnable); } @Override public Object resolveContextualObject(String key) { FacesContext facesContext = FacesContext.getCurrentInstance(); FacesRequestAttributes facesResquestAttributes = new FacesRequestAttributes(facesContext); return facesResquestAttributes.resolveReference(key); } @Override public String getConversationId() { FacesContext facesContext = FacesContext.getCurrentInstance(); FacesRequestAttributes facesResquestAttributes = new FacesRequestAttributes(facesContext); return facesResquestAttributes.getSessionId() + "-" + facesContext.getViewRoot().getViewId(); } private Map getViewMap(){ return FacesContext.getCurrentInstance().getViewRoot().getViewMap(); } } 

Ho provato a risolvere il problema della perdita di memoria del bean di visualizzazione Jsf sia per Jsf 2.1 che per Jsf 2.2. Prova il codice nel seguente link Perdita di memoria con il bean ViewScoped? . Cancellerà il bean di visualizzazione in sessione mentre navighi alla pagina successiva.