2009-04-23 281 views
6

我有一个Web应用程序中使用Spring和Hibernate与Struts(它运行在Tomcat)线程春季

调用顺序是这样的......

Struts动作调用春季服务豆这又调用Spring DAO bean。 DAO实现是一个Hibernate实现。

问题是 我所有的spring beans都运行在同一个线程中吗? 我可以存储在ThreadLocal的东西,并把它在另一个豆?

我敢肯定这不会在Stateless Session Bean的工作。 EJB容器可以(或将)为每个会话bean的调用产生一个新线程

弹簧容器的功能是否一样?即在同一个线程中运行所有的bean?在测试用例我通过Thread.currentThread()得到了相同的ID的getId()和两个beans-这使我相信,在行动

只有一个线程 -

当我试图JUnit测试。

或者是不可预知的行为? 还是会在Tomcat服务器上运行时更改?

澄清 我不希望在两个线程之间交换数据。我想将数据放入ThreadLocal中,并能够从调用堆栈中的所有bean中检索它。只有当所有的bean都在同一个线程中时,这才会起作用。

+0

你能发布一些示例代码吗?我不确定你想要达到什么目的。 – 2009-04-23 17:58:32

回答

15

Spring不生成线程。 Tomcat的确如此。春天只是为你创造和布置物体。

来自浏览器的每个请求在一个请求被处理。处理请求的是Tomcat。它是创建线程来处理请求的Tomcat。

假设您刚刚在Spring中创建了一个名为“X”的单例bean。然后,所有请求都使用同一个X实例。

春天豆不住在一个线程。他们只是分配在堆上。

+0

因此,当在Tomcat下运行时,我的端到端流将处于一个线程之下吗? – 2009-04-23 16:33:02

+0

是的,假设一切都在同一个应用程序服务器实例上。 – 2009-04-23 18:22:23

+0

这是迄今为止最好的解释。 – 2009-04-23 18:35:46

1

我所有的春豆都会在同一个线程中运行 吗?我可以将 东西在ThreadLocal中,并得到 它在另一个豆? AFAIK你提到的组件(服务bean,DAO bean - 我猜它们是普通的spring bean),Spring不会产生新的线程。我不明白你的用例(即在两个线程之间交换数据)。

对于大多数web应用中,产生新线程为每个新的请求,如果你想分享两个请求之间的数据,你通常: - 使用GET/POST参数来传递数据 - 使用会话分享数据

为了回答你的问题,我非常确定spring容器不会为大多数组件生成线程。

0

是的,你可以这样做。同一个线程将被用来执行你的动作,所以ThreadLocal将起作用。通常,同样的线程也用于无状态会话Bean,假设它运行在同一个应用服务器实例中。尽管如此,我不会依赖这个,因为它可能是供应商的依赖。

我们使用这种技术,以便随时随地访问呼叫者身份代码。我们也使用会话bean和jms,但明确地在容器之间传递信息并在每个入口点设置ThreadLocal。这样,无论bean(session或mdb)是否是本地的都没关系。

0

除了所有其他的答案,我只是补充如下:

通常要切换线程的唯一原因是因为parallellity一些要求。由于这通常不会在复杂性方面免费,所以通常会在发生这种情况时得到明确通知。内似乎是一个请求的单线程处理

切换线程实际上是极其复杂的。这通常只发生在容器中的一个地方,并且通常由接收来自外部客户端的请求的tcp/ip套接字读取器处理。这些读线程通常决定哪个线程(池)应该处理请求并将请求转发给该线程。之后,请求保留在该线程中。

所以通常会/可能发生的唯一的事情就是额外的线程获得并行性或异步处理(如JMS)创建的。