控制器(Spring Managed Bean)范围问题:单例、请求还是会话? [英] Controller (Spring Managed Bean) Scope Question: Singleton, Request or Session?

查看:32
本文介绍了控制器(Spring Managed Bean)范围问题:单例、请求还是会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The question is a bit long since it's conceptual. I hope it's not a bad read :)

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

I'm working in a performance critical Spring MVC/Tiles web-app (10,000 users typical load). We load an update employee screen, where we load an employee details screen (bound to an employee business object) for updates via a MultiActionController. There are multiple tabs on this screen, but only tab1 has the updatabale data. Rest of the tabs are read-only stuff, for reference basically.

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

Needless to say, we've decided to load these read-only tabs in a lazy manner, i.e., when each tab is activated, we fire an ajax call (one-time) for fetch the data from the server. We don't load everything via the update view loading method. Remember: this is one time, read-only data.

现在,我进退两难.我制作了另一个名为AjaxController"的多动作控制器来处理这些 ajax 调用.现在,我的问题:

Now, I'm in a dilemma. I've made another multiaction controller, named "AjaxController" for handling these ajax calls. Now, my questions:

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

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

Thoughts: If I make it request scoped, then 10,000 users together can create 10,000 instances of this bean: memory problem there. If I make it session scoped, then one will be created per user session. That means, when 10,000 users log in to the app, regardless of whether they hit the AjaxController methods, they will each have a bean in possession.

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

想法:spring 启动时会创建一个单例 bean,这个实例将贯穿始终.听起来不错.

Thoughts: A singleton bean will be created when spring boots, and this very instance will be provided throughout. Sounds good.

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

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

Thoughts: In this case, can havign static methods semantically conflict with the scope? For example: does scope="session"/"request" + static methods make sense? I ask because even though each user session has its own AjaxController bean, the handler methods are actually attached to the class, and not the instances. Also, does scope="singleton" + static handler methods make sense?

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

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

Thoughts: What if I control the creation: do the GoF singleton basically. Then what can the scope specification do? Scope session/request surely can't create multiple instances can they?

  1. 如果通过任何机制(bean 规范/设计模式/静态方法),我确实设法拥有一个 AjaxController 实例:这些 STATIC 方法需要同步吗?我认为不是,因为即使 STATIC 处理程序方法可以与需要时间的服务(与 DB/WS/MQ 等对话),我认为进入静态方法的每个请求线程都会由它们的线程 Id 返回,对吗?不是说user1进入了静态方法,然后user2在user1还没返回之前就进入了静态方法,然后都得到了一些乱码?这可能很愚蠢,但我想确定一下.

我很困惑.我基本上只想要一个控制器 bean 的单个实例,为所有客户端的所有请求提供服务.

I'm confused. I basically want exactly one single instance of the controller bean servicing all requests for all clients.

重要说明:AjaxController bean 没有在其他任何地方被注入,它是独立存在的.它的方法是通过 ajax 调用命中的.

Critical Note: The AjaxController bean is not INJECTED anywhere else, it exists isolated. It's methods are hit via ajax calls.

推荐答案

如果我这样做,我肯定会制作 LazyLoadController 单例,其中没有静态方法,也没有任何状态.

If I were doing this, I would definitely make the LazyLoadController singleton without having static methods in it and without any state in it.

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

Also, you definitely shouldn't instantiate singletons manually, it's better to use Spring's common mechanism and let the framework control everything.

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

The overall idea is to avoid using any static methods and/or persistent data in controllers. The right mechanism would be use some service bean for generating data for request, so controller acts as request parameter dispatcher to fetch the data out into the view. No mutable state or concurrently unsafe stuff should be allowed in controller. If some components are user-specific, Spring's AOP system provides injection of the components based on session/request.

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

That's about good practice in doing thing like that. There's something to clarify to give more specific answer for your case. Did I understand it right that typical use case for will be that AjaxController will pass some of requests to LazyLoadController to get tab data? Please provide details about that in comment or your question, so I may update my answer.

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

The thing that is wrong with having static methods in controller is that you have to manage concurrent safety by yourself which is not just error-prone but will also reduce overall performance. Spring runs every request in its own thread, so if two concurrent calls need to use some static method and there are shared resources (so you need to use synchronize statement or locks), one of threads will have to wait for another one to complete working in protected block. From the other hand, if you use stateless services and avoid having data that may be shared for multiple calls, you get increased performance and no need to deal with concurrent data access.

这篇关于控制器(Spring Managed Bean)范围问题:单例、请求还是会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆