【发布时间】:2011-12-30 01:24:33
【问题描述】:
我正在编写一个允许人们协作的 Web 应用程序。我希望我的一些服务范围仅限于协作(涉及几个人),而不是任何单独的 http 会话。我创建了一个自定义 Scope 来存储 bean。为了管理 bean 生命周期,我跟踪关联的会话 ID,如下所示:
protected ConcurrentMap<String,Object> attributes =
new ConcurrentHashMap<String, Object>();
...
@Override
public Object get(String name, ObjectFactory<?> factory) {
synchronized(this.attributes) {
Object scopedObject = this.attributes.get(name);
if (scopedObject == null) {
scopedObject = factory.getObject();
this.attributes.put(name, scopedObject);
RequestAttributes reqAttrs = RequestContextHolder.currentRequestAttributes();
activeSession(name).add(reqAttrs.getSessionId());
}
return scopedObject;
}
}
当会话关闭时,我想从与给定 bean 名称关联的活动会话列表中删除会话 ID。设置为空时,我可以清理。
我能想到的管理会话关闭的最简单方法是使用HttpSessionListener,但我的Scope 和侦听器之间存在断开连接。我看到以下可能性:
我可以静态创建
HttpSessionListener,假设一个单独的实例,让它管理一个订阅列表,并让我的Scope实例订阅它的事件。但这似乎是多余的,我不喜欢单例模式。如果我可以访问
Scope中的HttpSession,我可以将Scope添加到存储在会话中的列表中,并让侦听器通知该列表的成员会话正在离开。但我不知道如何在Scope实例中获取会话对象(而不仅仅是它的 id)。我可以让我的
Scope实现HttpSessionListener接口,从而直接更新其状态,但我不知道如何以编程方式注册监听器。有公开的方式吗?有没有更好的办法?
感谢您的帮助,
基因
【问题讨论】:
-
related question 有一个更“有弹性”的解决方案。
标签: java spring dependency-injection scope httpsession