Java 会话作用域bean未实例化

Java 会话作用域bean未实例化,java,spring,session,servlets,Java,Spring,Session,Servlets,我想创建一个会话范围的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 HttpSe

我想创建一个会话范围的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定义:

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

使用此配置时,不会有来自此类的日志,即使是来自构造函数或init()方法的日志。显然,Spring并没有创建这个bean。
通过反复试验,我检查了Spring是否在另一个bean需要时实例化了这样一个bean,例如UI使用的bean。还有别的(更好的)办法吗?春天是虫子吗?
使用的Spring版本:2.0.8。

HttpSessionActivationListener
javax.servlet.http
包的一部分。这应该给您一个提示,它应该由
Servlet
容器管理。在您的情况下,您没有通过
web.xml
SerlvetContainerInitializer
ServletContext
注册
侦听器

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

如果您使用的是
WebApplicationInitializer
,则可以实例化
注释配置webapplicationcontext
,创建
SessionLoggingListenerBean
bean,检索它并与一起使用

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

经过一些实验后,我认为最好不要使用弹簧。我修改了该类以实现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>

evo.log.SessionLoggingListener
从现在起,无论何时创建新会话,侦听器都会绑定到它(
session.setAttribute(…)
)。这对于让容器通知侦听器会话激活或钝化是必要的


对于Spring和会话-根据本协议,Spring在请求会话bean之前不会加载会话bean:

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


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

谢谢你的回答。我不能使用WebApplicationInitializer,因为我的Spring太旧了。我会尝试其他选择。