JSF View scope in Spring

后端 未结 5 1084
盖世英雄少女心
盖世英雄少女心 2020-11-30 07:14

Is there any scope like JSF @ViewScoped in Spring 3.0? I have an application using JSF+Spring where backing beans are managed by Spring. I didn\'t find any scop

相关标签:
5条回答
  • 2020-11-30 07:27

    I did something like this without Porting bean to Spring. It's working for 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);
           }
    }
    
    0 讨论(0)
  • 2020-11-30 07:41

    Recently I've created maven artifact which will solve this problem.

    See my github javaplugs/spring-jsf repository.

    0 讨论(0)
  • 2020-11-30 07:46
    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<String, Runnable> callbacks = (Map<String, Runnable>) 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<String, Runnable> callbacks = (Map<String, Runnable>) 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<String, Object> getViewMap(){
    return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
    }
    
    }
    
    0 讨论(0)
  • 2020-11-30 07:49
    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<String, Runnable>()
          );
    
        } else if (event instanceof PreDestroyViewMapEvent) {
          PreDestroyViewMapEvent viewMapEvent = (PreDestroyViewMapEvent) event;
    
          UIViewRoot viewRoot = (UIViewRoot) viewMapEvent.getComponent();
    
          Map<String, Runnable> callbacks = (Map<String, Runnable>) 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;
      }
    }
    
    0 讨论(0)
  • 2020-11-30 07:53

    I have tried a work around for the Jsf view bean memory leak issue for both Jsf 2.1 & Jsf 2.2. Try the code in following link Memory leak with ViewScoped bean?. It will clear the view bean in session while navigating to next page.

    0 讨论(0)
提交回复
热议问题