<listener>
<listener-class>com.netvour.commons.listener.SessionListener</listener-class>
但等我真正应用到这监听器却一直报空指针异常,debug后才发现,原来
@Autowired
private SysUserService sysUserService;
拿到的是null,上网查了才知道,监听器是属于servlet容器的,而不是spring 管理的, 无法通过应用spring的注解去引入业务类对象(-_-|||)~~
既然知道问题了,接下来就是找解决方式了。 直接在实现一个接口,ServletContextListener接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。
ServletContextListener有两个方法需要重写(实现),一个是contextInitialized(ServletContextEvent sce)方法,当Servlet 容器启动Web 应用时调用该方法。在调用完该方法之后,容器再对Filter 初始化,并且对那些在Web 应用启动时就需要被初始化的Servlet 进行初始化;一个是contextDestroyed(ServletContextEvent sce)方法,当Servlet 容器终止Web 应用时调用该方法。(在调用该方法之前,容器会先销毁所有的Servlet 和Filter 过滤器)。
而我们需要做的就是,在contextInitialized(ServletContextEvent sce)中,获取到业务类对象,代码如下:
public class SessionListener implements ServletContextListener,HttpSessionListener{
private SysUserService sysUserService;
@Override
public void sessionCreated(HttpSessionEvent se) {}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//业务方法
SysUserLoginVo so = (SysUserLoginVo) se.getSession().getAttribute("user");
if(so!=null){
SysUserLoginVo tmp = new SysUserLoginVo();
tmp.setStatus(2);
boolean flag = sysUserService.updateSysUserInfo("listener",tmp);
if(flag){
System.out.println("session过期,自动更新用户状态成功");
}else{
System.out.println("session过期,自动更新用户状态失败");
}
}
}
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
ApplicationContext context = (ApplicationContext) servletContext.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//initialize service when spring context initialized,
//建立对应的service当spring上下文初始化之后
//使用spring框架中已经初始化的sysUserService
sysUserService = (SysUserService)context.getBean(SysUserService.class);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {}
}