4
respostas

@ViewScoped com Spring MVC

Considerando que os beans possui somente a anotação @Controller. Como o Spring MVC garante o escopo de view e sessão?

4 respostas

Olá,

Tem uma resposta aqui: http://stackoverflow.com/questions/2249706/spring-mvc-vs-jsf

"Spring MVC, as it's a request-based framework like Struts."

"JSF is component-based, which is a bit different paradigm from request-based frameworks."

Spring MVC é um framework baseado em requisição (request).

E aqui cita como manter o estado entre requisições: http://stackoverflow.com/questions/1856440/maintain-state-with-spring-between-requests.

"You can either put the modelMap in the HttpSession, or (preferable for larger applications), use Spring web flow where you can have the so called conversations."

Você pode colocar o modelMap dentro do HttpSession ou (preferencialmente para grandes aplicações) usar Spring Web Flow onde você pode ter as tão chamadas conversações.

O Spring nao possui view scope, por isso voce tera que criar o seu proprio @scope("view").

1) O spring te da suporte para criacao de um novo escopo

public class ViewScope implements org.springframework.beans.factory.config.Scope {

  public Object get(String name, ObjectFactory<?> objectFactory) {
    if (FacesContext.getCurrentInstance().getViewRoot() != null) {
      Map<String, Object> viewMap = FacesContext.getCurrentInstance()
             .getViewRoot()
             .getViewMap(); // Map do JSF cujo os valores são referentes ao escopo de view
      if (viewMap.containsKey(name)) {
        return viewMap.get(name);
      } else {
        Object object = objectFactory.getObject();
        // da próxima vez que for requisitado, dentro do escopo de view,
        // ele não precisará ser construído.
        viewMap.put(name, object);
        return object;
      }
    } else {
      return null;
    }
  }

  public Object remove(String name) {
    if (FacesContext.getCurrentInstance().getViewRoot() != null) {
      // simplesmente, remove o bean Spring do ViewMap do JSF
      return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
    } else {
      return null;
    }
  }

  ...
}

2) Agora vc precisa invocar o metodo register scope

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

  void registerScope(String scopeName, Scope scope);

  ...
}

@Configuration
public class ViewScopeConfig {

    @Bean
    public static CustomScopeConfigurer customScopeConfigurer() {
        Map<String, Object> scopes = new HashMap<>();
        scopes.put("view", new ViewScope());

        CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer();
        customScopeConfigurer.setScopes(scopes);

        return customScopeConfigurer;
    }
}

3) Por ultimo, basta anotar seu Managed Bean com as seguinte annotations:

@Component
@Scope("view")

Olá,

O framework JoinFaces (Spring Boot + JSF) criou o escopo @ViewScope também: https://github.com/joinfaces/joinfaces/blob/master/joinfaces-autoconfigure/src/main/java/org/joinfaces/autoconfigure/integration/ViewScope.java