Spring请求范围与java线程本地
在高容量(每秒约50000个请求)的java web应用程序中,我使用ThreadLocal来执行一项任务,该任务应该在每个请求范围内执行
我可以使用Spring请求范围实现同样的效果,我想知道哪种性能更好
在代码中,使用ThreadLocal:
private static final ThreadLocal<SomeClass> myThreadLocal = new ThreadLocal<SomeClass>();
对于每个http请求设置:
myThreadLocal.set(new SomeClass());
使用Spring请求范围:
@Component
@Scope("request")
public class SomeClass{
...
}
现在,什么成本更高:
myThreadLocal.get();
或
SpringContext.getBean(SomeClass.class);
我想知道是否有人已经尝试过这样的基准
# 1 楼答案
引用JavaDoc中关于反射的内容-http://java.sun.com/docs/books/tutorial/reflect/index.html
因此,由于Spring在
getBean()
方法中使用了反射,因此SpringContext.getBean(SomeClass.class);
方法应该较慢编辑:
还请注意
ThreadLocal
还嵌入了缓存,因此只要在这些线程中重用信息,肯定会更快# 2 楼答案
关于
ThreadLocal
解决方案,我想补充一点,您的web服务器中可能有一个线程池(例如:Tomcat),并且您的线程局部变量实际上不会在每个请求完成时被清除,因为在启用线程池的情况下,处理线程不会死亡您需要在每个请求完成后手动清除线程局部变量(
threadLocal.remove()
)。例如,您可以使用一些Spring请求/响应拦截器的某种afterCompletion()
# 3 楼答案
Spring解决方案将花费更多,但将使IMO的代码更干净。获取、创建、初始化和存储bean涉及很多步骤。但是,您不必像清除
ThreadLocal
那样考虑清除请求范围的bean。当相应的ServletRequest
被清除时,它将被收集