2011-11-16 5 views
2

私は人々が共同作業できるWebアプリケーションを作成しています。個々のhttpセッションではなく、いくつかの人が関わっているコラボレーションに範囲を絞ってサービスを提供したいと考えています。私は豆を保管するカスタムScopeを作成しました。豆のライフサイクルを管理するために、私は次のように関連付けられたセッションIDを追跡:HttpSessionListenerでスコープを接続する

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とリスナーの間を切断しています。

  1. 私は、静的HttpSessionListenerを作成する唯一のインスタンスを想定し、それはサブスクリプションのリストを管理していて、私のScopeインスタンスがそのイベントにサブスクライブすることができ:私は、次の可能性を参照してください。しかし、それは重複しているように見えますが、私はこのためのシングルトンのパターンが嫌いです。私はScopeHttpSessionへのアクセスを持っていた場合

  2. 、私はセッションに格納されたリストにScopeを追加し、リスナーがセッションを離れて起こっているそのリストのメンバーに通知する可能性があります。しかし、私はどのようにScopeインスタンスのセッションオブジェクト(そのIDだけではなく)に手を差し伸べるか分かりません。

  3. 私はScopeHttpSessionListenerインターフェイスを実装して、その状態を直接更新することができますが、プログラムでリスナーを登録する方法はわかりません。それを行う公的な方法はありますか?

  4. もっと良い方法がありますか?

次のようにご協力いただきありがとうございますが、

遺伝子

+0

[Springy]解決策がある[関連する質問](http://stackoverflow.com/questions/2433321/how-to-inject-dependencies-into-httpsessionlistener-using-spring)があります。 – Eyal

答えて

2

は、任意のコメントや答えを受け取ったない、私は、オプション#1と一緒に行きました:

public class SessionMonitor implements HttpSessionListener { 
    protected final Log logger = LogFactory.getLog(getClass()); 

    protected CopyOnWriteArrayList<SessionEventListener> subscribers = new CopyOnWriteArrayList<SessionEventListener>(); 
    protected ConcurrentHashMap<String,HttpSession> sessions = new ConcurrentHashMap<String,HttpSession>(); 
    protected static SessionMonitor singleton; 
    public static SessionMonitor soleInstance() throws ConfigurationException { 
     if (singleton == null) 
      throw new ConfigurationException("No SessionMonitor instance has been created"); 
     return singleton; 
    } 

    public SessionMonitor() { 
     if (singleton == null) 
      singleton = this; 
    } 

    @Override 
    public void sessionCreated(HttpSessionEvent e) { 
     HttpSession session = e.getSession(); 
     this.sessions.putIfAbsent(session.getId(), session); 
     logger.trace("Registered session " + session.getId()); 
    } 

    @Override 
    public void sessionDestroyed(HttpSessionEvent e) { 
     String sessionId = e.getSession().getId(); 
     this.sessions.remove(sessionId); 
     for (SessionEventListener listener: subscribers) 
      listener.sessionEnded(sessionId); 
     logger.trace("Removed session " + sessionId); 
    } 

    public HttpSession getSession(String id) { 
     return this.sessions.get(id); 
    } 

    public void addListener(SessionEventListener listener) { 
     this.subscribers.add(listener); 
     logger.trace("Added listener " + listener); 
    } 

    public void removeListener(SessionEventListener listener) { 
     this.subscribers.remove(listener); 
     logger.trace("Removed listener " + listener); 
    } 
} 

範囲が取得します作成されると、それ自体に登録します。SessionMonitor

public ConditionalScope() throws ConfigurationException { 
    logger.debug("Registering " + this.toString() + " for session monitoring"); 
    SessionMonitor.soleInstance().addListener(this); 
} 

SessionMonitorからScopeを削除する時期は明確ではありません。 WeakArrayのいくつかの並べ替えはここですか?

関連する問題