2013-12-12 218 views
0

我想创建一个会话范围的bean来监视HTTP会话的激活和钝化。豆是非常简单的:未实例化会话范围的bean

package my.log; 

import javax.servlet.http.HttpSessionActivationListener; 
import javax.servlet.http.HttpSessionEvent; 

import org.apache.log4j.Logger; 

public class SessionLoggingListenerBean implements HttpSessionActivationListener { 
    private final Logger LOG = Logger.getLogger(this.getClass()); 

    public SessionLoggingListenerBean() { 
     LOG.info("SessionLoggingListenerBean starting"); 
    } 

    public void init() { 
     LOG.info("SessionLoggingListenerBean init"); 
    } 

    public void sessionDidActivate(HttpSessionEvent event) { 
     LOG.info("Session " + event.getSession().getId() + " activated"); 
    } 

    public void sessionWillPassivate(HttpSessionEvent event) { 
     LOG.info("Session " + event.getSession().getId() + " will passivate"); 
    } 
} 

豆定义在应用程序上下文:

<bean id="sessionLoggingListenerBean" class="my.log.SessionLoggingListenerBean" scope="session" init-method="init" lazy-init="false"/> 

根据该结构没有从这个类日志,甚至从构造或init()方法。显然,Spring不创建这个bean。
通过试验和错误我检查到Spring在另一个bean需要它的时候实例化了这样一个bean,例如,由UI使用。有没有其他(更好)的方法?这是Spring的错误吗? 使用的春天版本:2.0.8。

回答

0

使用一些尝试后,我认为这是最好不要使用Spring此目的。我已经修改了类也HttpSessionListener补偿实施和Serializable接口

public class SessionLoggingListener implements HttpSessionListener, 
    HttpSessionActivationListener, Serializable { 
private static final long serialVersionUID = -763785365219658010L; 
private static final Logger LOG = Logger.getLogger(SessionLoggingListener.class); 

public SessionLoggingListener() { 
    LOG.info("SessionLoggingListener created"); 
} 

public void sessionDidActivate(HttpSessionEvent event) { 
    LOG.info("Session " + event.getSession().getId() + " activated"); 
} 

public void sessionWillPassivate(HttpSessionEvent event) { 
    LOG.info("Session " + event.getSession().getId() + " will passivate"); 
} 

public void sessionCreated(HttpSessionEvent event) { 
    final HttpSession session = event.getSession(); 
    LOG.info("Session " + session.getId() + " created. MaxInactiveInterval: " + session.getMaxInactiveInterval() + " s"); 
    session.setAttribute(this.getClass().getName(), this); 
} 

public void sessionDestroyed(HttpSessionEvent event) { 
    LOG.info("Session " + event.getSession().getId() + " destroyed"); 
    event.getSession().removeAttribute(this.getClass().getName()); 
} 

} 

,并把它添加到web.xml中:

<listener> 
    <listener-class> 
     evo.log.SessionLoggingListener 
    </listener-class> 
</listener> 

从现在开始,只要创建一个新的会话,听者结合它(session.setAttribute(...))。这对于使容器注意到有关会话激活或钝化的侦听器是必需的。


在春季和会议的情况 - 根据本forum thread,直到他们被要求春节不加载会话bean:

会话bean被视为“原型”的一种特殊形式。这意味着它将在创建实例时遵循原型语义。

对我来说这是一个不直观的,没有很好记录的行为。

2

HttpSessionActivationListenerjavax.servlet.http包的一部分。这应该给你一个暗示,它应该由Servlet容器来管理。在你的情况下,你没有注册Listener你的ServletContext,既不通过web.xmlSerlvetContainerInitializer

通过web.xml您将无法将它同时作为Spring和Servlet容器管理对象,因此改为存在这些解决方法,first,second

如果您使用的是WebApplicationInitializer,你可以实例化AnnotationConfigWebApplicationContext,已在SessionLoggingListenerBean豆创建,检索与

SessionLoggingListenerBean yourBean = context.getBean(SessionLoggingListenerBean.class); 
servletContext.addListener(yourBean); 
+0

感谢您的回答。由于我的Spring太老,我无法使用WebApplicationInitializer。我会尝试其他选项。 – pkalinow