如果我的 web 应用程序和 ejb 应用程序在同一台机器上(在同一个 JVM 上)并且所有 ejb 调用都是本地调用,那么ThreadLocal
在将信息从 web 传递到 ejb 时使用会产生任何问题吗?
如果 ejb 调用是远程的,有什么解决方法吗?ThreadLocal
信息是否可以从 Web 应用程序到 ejb 应用程序?ThreadLocal
在这种情况下是否建议使用?
如果我的 web 应用程序和 ejb 应用程序在同一台机器上(在同一个 JVM 上)并且所有 ejb 调用都是本地调用,那么ThreadLocal
在将信息从 web 传递到 ejb 时使用会产生任何问题吗?
如果 ejb 调用是远程的,有什么解决方法吗?ThreadLocal
信息是否可以从 Web 应用程序到 ejb 应用程序?ThreadLocal
在这种情况下是否建议使用?
对于第一个问题,只要在每次调用结束时去掉 ThreadLocal 变量就没有问题。这很重要,因为容器(servlet 或 ejb)通常使用线程池并因此重用线程,这有两个影响:一个“调用”可能会看到来自先前调用的线程本地信息,以及如果您在不停止 JVM 的情况下从容器中删除应用程序有些类可能不会被垃圾回收,因为它们仍然被容器线程引用。因此,将数据放在 try / finally 块中的 threadlocal 中,并在 finally 部分中删除。
这是一篇文章,展示了一种处理问题的方法:Web 应用程序中的 ThreadLocal
对于第二个问题,因为数据是线程本地的,它不会随远程调用一起提供,您必须在接口中添加一个参数,在一侧提取线程本地数据并在另一侧重新创建它......
使用 EJB 3.1 时,您可以使用 EJBContext 的上下文数据在EJBContext中传递上下文信息。这只是一个.Map<String,Object>
不应在 EJB 上下文中使用 ThreadLocal。不能保证 EJB 方法调用都在同一个线程上(当然应该如此)。
在 EJB 中有一种不同的方法,称为TransactionSyncrhonizationRegistry。有关详细信息,请参阅说明/用法。
所有 ejb 调用都是本地调用,使用 ThreadLocal 会产生任何问题吗?
不,你自己回答了你的问题。由于调用是本地的,它们在一个线程的上下文中执行。
如果 ejb 调用是远程的,有什么解决方法吗?
在远程调用的情况下,Java EE 容器将在另一个 JVM 中运行,它将产生自己的线程来处理传入的 RMI 请求,远程 Java EE 容器无法知道在其上声明的线程局部变量另一边。将其作为参数对象传递。
这取决于你传递什么信息!第一个问题太笼统了。我建议在这里阅读与 ThreadLocal 相关的 JavaDoc 。
ThreadLocal 来自应用程序的服务器端,用于让线程安全地调用 Thread 对象。
对于本地调用,ThreadLocal
只要一切都在同一个线程中完成,应该可以正常工作。
对于可能在不同服务器上运行的远程调用,您将需要提出其他方法。要么将所有值作为参数传递(这将起作用,但会在代码中引入复杂性),要么使用分布式缓存之类的东西,例如Hazelcast,它的功能类似于HashMap
所有集群节点都可以访问的 global 。
ThreadLocal
不能 100% 确定地在 Web 应用程序中使用。您根本无法保证一个线程将用于一个会话。在我看来,这可能会导致很难找到安全漏洞!
ctx.getContextData()
对我不起作用,它总是返回null
!
我也试过了TransactionSynchronizationRegistry
,但我也得到null
了。
唯一有效的是使用 JAAS 作为解决方法。但这不是一个好的解决方案。