使用 ThreadLocal 对象存储 Web 请求元数据是一种不好的做法吗?

Ald*_*ian 3 java thread-local jakarta-ee

我正在开发一个分为几个模块的 j2ee webapp。我有一些元数据,例如用户名和首选项,我想从应用程序的任何地方访问它们,并且可能还收集类似于日志信息但特定于请求的数据并将其存储在这些元数据中,以便我可以选择将其发回作为调试信息给用户。

除了在从上层表示类到下层 daos 的每个方法中传递通用上下文对象或使用 AOP 之外,想到的唯一解决方案是使用与会话 BTW 非常相似的线程本地“上下文”对象,并为对正在进行的请求进行绑定并在响应时解除绑定。

但是这样的事情感觉有点麻烦,因为这打破了几种模式,并且在测试和调试时可能会使事情变得复杂,所以我想问一下根据您的经验是否可以这样进行?

Enn*_*oji 5

就我个人而言,我更喜欢传递上下文对象,因为使用同一线程进行处理的事实是实现的产物,您不应该依赖此类工件。当你想使用其他线程时,你会碰壁。

如果这些状态被封装在一个 Context 对象中,我认为这已经足够干净了。


ino*_*nor 5

ThreadLocal 是一种弥补糟糕设计和/或架构的黑客。这是一个糟糕的做法:a)它是一个或多个全局变量的池,任何语言中的全局变量都是不好的做法(有一系列与全局变量相关的问题 - 在网上搜索)b)它可能会导致记忆泄漏,在任何 j2ee 容器中,而不是管理它的线程,如果你处理得不好。

更糟糕的做法是在各个层中使用 ThreadLocal。从一层传输到另一层的数据应该使用传输对象(一种标准模式)传递。

很难想出一个使用 ThreadLocal 的好理由。也许如果你需要在两个层之间传达一些值,它们之间有第三层/中间层,而你没有办法对该中间层进行更改......但如果是这种情况,我会寻找一个更好的中间层。
在任何情况下,如果您将值存储在代码中的一个特定点并在另一个点检索它,那么这可能是情有可原的,否则您永远不知道哪一面会影响任何执行方法可能对 ThreadLocal 中的值产生影响。