EJB 容器中的 ThreadLocal(和 Singleton)
我编写了一个授权系统,它依赖于代表当前用户的对象。为了简化编程并提高性能,我想在用户登录后将这些对象保存在 ThreadLocal 中。
它看起来像这样:
public class UserCache {
private static final ThreadLocal<User> cache = new ThreadLocal<User>();
public User getCurrentUser() {
return cache.get();
}
public void setCurrentUser(User user) {
cache.set(user);
}
}
我读到静态元素会使集群出现问题。如果我在每个集群节点上都有一个 UserCache,那么它们都有自己的缓存对象,不与其他节点上的缓存对象同步。正确的? UserCache
是单例的典型候选者,因为应用程序只需要它的一个实例。但据我所知,@Singleton EJB 在集群中具有相同的行为。
那么如何使 UserCache 在 EJB 3.1 (Java EE 6) 环境中可集群呢?
从答案中提取的解决方案:
- 使用 CDI (JSR 299) 中的 SessionScope 或
- 使用 Terracotta 中的 JVM 集群
I've written an authorization system which relies on objects representing the current user. To simplify programming and increase performance I want to hold those objects in a ThreadLocal after the user has logged in.
It looks like this:
public class UserCache {
private static final ThreadLocal<User> cache = new ThreadLocal<User>();
public User getCurrentUser() {
return cache.get();
}
public void setCurrentUser(User user) {
cache.set(user);
}
}
I've read that static elements make clustering problematic. If I had an UserCache on each cluster node, they all had their own cache object not synchronized with the cache objects on other nodes. Right? UserCache
is a classic candidate for a singleton, because the application needs only a single instance of it. But as far as I know @Singleton EJBs have the same behaviour in a cluster.
So what to do to make UserCache clusterable in an EJB 3.1 (Java EE 6) environment?
Solutions extracted from the answers:
- Using SessionScope from CDI (JSR 299) or
- Using JVM clustering with Terracotta
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
既然您已经在使用 Java EE 6,那么使用 CDI(上下文和依赖注入)不是更容易吗?这将允许将用户信息放入会话范围,并轻松地将其注射到任何地方。 CDI 会为您管理剩下的事情。
Since you're already on Java EE 6, wouldn't it even be a lot easier to use CDI (Contexts and Dependency Injection). This would allow to put the user info in the session scope, and inject it easily everywhere. CDI manages the rest for you.
这不应该给你带来问题,因为线程无论如何都不会跨越不同的节点 - 或者我错过了你的问题的要点?
编辑:你可能想研究一下类似 terracotta 的东西 - http://www.terracotta.org/ -了解对现有对象进行聚类的方法
that shouldn't cause you a problem, because threads don't span different nodes anyway - or am i missing the point of your question?
edit : you might want to look into something like terracotta - http://www.terracotta.org/ - for ways you can cluster existing objects
如果您需要在节点之间共享对象,我还建议查看现有框架(如 Terracotta)。
此外,使用 ThreadLocal 可能会导致不同的问题:
http://forums.sun.com/ thread.jspa?threadID=589744
http://www.devwebsphere.com/devwebsphere/2005/06/dont_use_thread。 html
http://www.theserverside.com/discussions/thread.tss?thread_id= 21055
不过,这在这里可能不是问题。
If you need to share objects between nodes, I would also suggest looking at the existing frameworks (like Terracotta).
Also, using ThreadLocal might possibly cause different problems:
http://forums.sun.com/thread.jspa?threadID=589744
http://www.devwebsphere.com/devwebsphere/2005/06/dont_use_thread.html
http://www.theserverside.com/discussions/thread.tss?thread_id=21055
This may not be an issue here, though.