当前位置: 首页 > 知识库问答 >
问题:

Spring请求范围与java线程本地

傅自明
2023-03-14

在大容量(每秒约50,000个请求)的java Web应用程序中,我使用Threadloce-app执行一个任务,该任务应按请求范围执行。

我可以使用Spring请求范围实现相同的效果,我想知道哪种性能更好?

在代码中,使用线程本地:

private static final ThreadLocal<SomeClass> myThreadLocal = new ThreadLocal<SomeClass>();

对于每个超文本传输协议请求设置:

myThreadLocal.set(new SomeClass());

使用Spring请求范围:

@Component
@Scope("request")
public class SomeClass{
...
}

现在,什么成本更高:

myThreadLocal.get();

SpringContext.getBean(SomeClass.class);

不知道有没有人已经尝试过这样的标杆了呢?

共有3个答案

何涵育
2023-03-14

Spring解决方案的成本会更高,但会使IMO的代码更干净。获取、创建、初始化和存储bean涉及很多步骤。但是,您不必像清除ThreadLocal那样考虑清除请求范围的bean。当相应的ServletRequest被清除时,它将被收集。

方飞翼
2023-03-14

关于ThreadLocal解决方案,我想补充的是,在您的Web服务器中可能有一个线程池(例如:Tomcat),并且您的线程本地变量实际上不会在每次请求完成后被清除,因为处理线程不会随着线程而死亡已启用池。

您需要在完成每个请求时手动清除线程本地变量(threadLocal.remove())。例如,您可以使用一些Spring请求/响应拦截器的某种postComplments()

沈运恒
2023-03-14

如果我们考虑传统的Java方法,答案可以从下面的报价中扣除,因为要慢得多:

由于反射涉及动态解析的类型,因此无法执行某些Java虚拟机优化。因此,反射式操作的性能比非反射式操作要慢,应该避免在性能敏感应用程序中频繁调用的代码段中使用反射式操作。

引用JavaDoc中关于反射的内容-http://java.sun.com/docs/books/tutorial/reflect/index.html

因此,由于Spring使用反射与getBean()方法,所以SpringContext.getBean(lass.class);方法应该更慢。

编辑:

还要注意的是,ThreadLocal也嵌入了缓存,因此只要在这些线程中重用信息,肯定会更快。

 类似资料:
  • 我现在尝试了很多东西,但我似乎错过了一块拼图。故事是这样的:我有一个请求范围的bean,它从HttpServletRequest读取一些SessionContext。此属性在过滤器中设置。因此,当代码在正确的线程上运行时,这是非常好的。 现在我开始使用java 8s的新功能CompletableFuture,我有其中三个功能在请求线程等待结果时并行计算东西。我想做的是提升/移交/传播bean或请求

  • 我想在我的web应用程序中使用Spring事件与我的bean“说话”。 例如,fired事件的bean如下所示: 所以,我的问题是: 事件侦听器是作用域请求是否可能?而如何做到这一点呢? 谢谢

  • 无论 Struts2 还是 Spring,都提供了一种控制器: 每次请求,创建实例,使用后即抛弃。 这样的控制器的好处就是可以放心的吧 request 和 response 对象放心的存成它的私有 属性,反正使用一次后就丢掉了。 在 Nutz.Mvc,所谓控制器,实际上就是 Module,默认的,所有的模块都是整个应用程序唯一的, 除非你在 Ioc 配置文件里另有说明。 那么 Nutz 可以做到每

  • 基于CGLIB的请求范围bean的堆栈跟踪() 基于JDK-Dynamic-Proxy-Interface的请求范围bean的堆栈跟踪()

  • 更改TestResource 并向QueryFactory添加 我理解使用请求范围需要。然而,当我运行它时,我得到一个异常,它告诉我 我看不出哪里出了问题。你能给我指出这个配置应该如何正确地完成吗?

  • 从WebSocketendpoint,我尝试调用单例服务。但是我无法使用来自WebSocket的请求或会话范围。 谢谢你的帮助!