控制器(Spring Managed Bean)范围问题:单例,请求还是会话?

Spr*_*sed 5 model-view-controller spring controller javabeans

这个问题有点长,因为它是概念性的.我希望这不是一个糟糕的读:)

我正在使用性能关键的Spring MVC/Tiles web-app(10,000个用户典型负载).我们加载更新员工屏幕,我们在其中加载员工详细信息屏幕(绑定到员工业务对象)以通过MultiActionController进行更新.此屏幕上有多个选项卡,但只有tab1具有可更新数据.其余的标签是只读的东西,基本上可供参考.

不用说,我们决定以懒惰的方式加载这些只读选项卡,即,当每个选项卡被激活时,我们触发ajax调用(一次性)以从服务器获取数据.我们不会通过更新视图加载方法加载所有内容.请记住:这是一次只读数据.

现在,我处于两难境地.我已经创建了另一个多路动作控制器,名为"AjaxController"来处理这些ajax调用.现在,我的问题:

  1. 什么应该是这个控制器的最佳范围?

思考:如果我让它请求作用域,那么10,000个用户一起可以创建10,000个这个bean的实例:内存问题.如果我将其作为会话范围,那么将为每个用户会话创建一个.这意味着,当10,000个用户登录到应用程序时,无论他们是否使用AjaxController方法,他们都将拥有一个bean.

  1. 那么,singleton是这个控制器的最佳范围吗?

想法:弹簧靴时会创建一个单独的bean,这个实例将在整个过程中提供.听起来不错.

  1. 处理程序方法(如fetchTab7DataInJsonFormat)是静态的并附加到类中吗?

思考:在这种情况下,是否可以在静态方法上与语境冲突?例如:scope ="session"/"request"+静态方法有意义吗?我问,因为即使每个用户会话都有自己的AjaxController bean,处理程序方法实际上附加到类,而不是实例.另外,scope ="singleton"+静态处理程序方法是否有意义?

  1. 我可以手动将单例设计模式实现到AjaxController中吗?

想法:如果我控制创作怎么办:基本上做GoF单身.然后范围规范可以做什么?范围会话/请求肯定无法创建多个实例吗?

  1. 如果通过任何机制(bean规范/设计模式/静态方法),我确实设法有一个AjaxController实例:这些STATIC方法是否需要同步?我想不是,因为即使STATIC处理程序方法可以与需要时间的服务(与DB/WS/MQ等交谈)进行通信,我认为每个请求线程进入静态方法都会被它们的线程ID返回吗?它不像user1进入静态方法,然后user2在返回user1之前进入静态方法,然后它们都得到一些乱码数据?这可能很傻,但我想确定.

我糊涂了.我基本上只需要一个控制器bean的单个实例来为所有客户端提供所有请求.

重要说明:AjaxController bean在其他任何地方都不是INJECTED,它是隔离的.它的方法是通过ajax调用命中的.

Vad*_*rov 3

如果我这样做,我肯定会创建 LazyLoadController 单例,其中不包含静态方法,也不包含任何状态。

另外,你绝对不应该手动实例化单例,最好使用 Spring 的通用机制,让框架来控制一切。

总体思想是避免在控制器中使用任何静态方法和/或持久数据。正确的机制是使用一些服务 bean 来生成请求数据,因此控制器充当请求参数调度程序以将数据提取到视图中。控制器中不应允许任何可变状态或并发不安全的内容。如果某些组件是特定于用户的,Spring的AOP系统提供基于会话/请求的组件注入。

这就是做类似事情的良好实践。有一些事情需要澄清,以便为您的案例提供更具体的答案。我是否理解正确,典型的用例是 AjaxController 将一些请求传递给 LazyLoadController 以获取选项卡数据?请在评论或您的问题中提供有关详细信息,以便我可以更新我的答案。

在控制器中使用静态方法的错误在于,您必须自己管理并发安全性,这不仅容易出错,而且还会降低整体性能。Spring在自己的线程中运行每个请求,因此如果两个并发调用需要使用某些静态方法并且存在共享资源(因此需要使用同步语句或锁),则其中一个线程将不得不等待另一个线程完成工作在受保护的块中。另一方面,如果您使用无状态服务并避免拥有可能为多个调用共享的数据,您将获得更高的性能,并且无需处理并发数据访问。