弹簧控制器范围和存储会话数据

时间:2013-07-20 18:10:57

标签: java spring spring-mvc

我是弹簧范围的新手。

我有一个代码如下

   @Controller
   public class PageController extends AbstractController {

private ABCManager abcManager;// repository singleton bean.

@Inject
public PageController(final ABCManager accountDiaryManager){
    this.abcManager= abcManager;
}

    @RequestMapping(value="/createpage",method=RequestMethod.POST)
public @ResponseBody Page createPage(@RequestParam(value="viewtype")final String viewtype, final WebRequest request)
    {
    final ABC abc= (abc) request.getAttribute(AbstractController.CURRENT_ABC, WebRequest.SCOPE_SESSION);

        .........
       abcManager.createPage(Long.valueOf(abc.getId()), page);
request.setAttribute("abc", abcManager.getabc(abc.getId()),WebRequest.SCOPE_SESSION);
 }

由于abc对象可以在同一用户会话中多次更改,因为abc是根对象并包含树结构,用户操作将涉及更改子对象中的任何位置。因此,当执行编辑时,我将修改后的abc对象保存在请求中,以便每次在请求中都可以使用最新的abc对象。这个abc可以变得非常大,这是我关心的问题。是这样做的好方法吗?

我想知道这样做是否是一个很好的做法。这是一种线程安全的方式吗?什么是最好的替代品。

1 个答案:

答案 0 :(得分:0)

  1. Get / Put to session对象不是线程安全的。在您的情况下,由于您在会话中存储与特定用户相关的数据,因此只要您不希望同一用户执行可以同时更新会话的多个操作,就可以安全地执行此操作。话虽如此,如果你真的在开发一个生产就绪系统,在这种情况下你将最终得到多个应用服务器,你需要考虑你的会话管理策略 - 你可以在webserver上使用粘性会话(Apache httpd例如)以便属于同一会话的所有请求都转发到同一个应用服务器,或者您需要在应用服务器之间启用会话复制。

  2. ABC变得非常大,需要量化。如果您假设它的大小增长到1MB,并且您已经为应用服务器的JVM分配了2 GB RAM,并且假设其中1 GB可用于应用程序的内存要求,则可以存储多达1000个用户的数据。根据您计划支持的并发会话数量,您必须配置适量的RAM。

  3. 如果ABC存储瞬态数据,例如购物车信息,并且您可以在服务器重启期间丢失,那么您的方法就可以了。如果您不想丢失数据,那么,您可以考虑使用缓存系统或NoSQL存储的键值类型(CouchBase,Redis等)。 RDBMS也是一个选项,但它实际上取决于您尝试在会话中维护的数据的性质以及它们是否确实具有会话语义,或者您只是为了方便而将它们存储在会话中。