Java 会话作用域bean未实例化
我想创建一个会话范围的bean来监视HTTP会话的激活和钝化。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
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太旧了。我会尝试其他选择。