为方便有时希望在监听器中使用 Spring 框架中的某些 service,但是因为监听器属于sevlet容器,不属于 Spring 框架的管理范围,所以如果期望监听器中直接使用 @Resource 等注解加载 service 的做法是错误,报 null 指针异常,那如果图简单想直接使用,正确做法是实现 Spring 的 ServletContextListener 接口,在 Spring 上下文初始化事件完成后,再查找 Spring 框架中(上下文)的对应的 service 然后再提供给监听器使用,代码如下:
package com.xxx.yyy.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import com.xxx.yyy.entity.Member;
import com.xxx.yyy.module.service.MemberService;
/**
* @author shenzhenNBA
* @since 2017.04.17
*/
//@Slf4j
public class AppSessionListener implements ServletContextListener,HttpSessionListener {
//@Resource //监听器属于sevlet容器而非spring管理范围,故不能使用注解方式加载相关实例
private MemberService memberService;
@Override
public void sessionCreated(HttpSessionEvent hse) {
HttpSession session = hse.getSession();
// session createed to do...
}
@Override
public void sessionDestroyed(HttpSessionEvent hse) {
HttpSession session = hse.getSession();
try {
String memberId = (String)session.getAttribute("memberId");
Member member = memberService.findByMemberId(memberId);
//to do more when session destroyed...
} catch (Exception e) {
//log.error("异常!", e);
}
}
@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框架中已经初始化的memberService
memberService = (MemberService)context.getBean(MemberService.class);
//to do more...
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
web.xml 配置 listener
<listener>
listener-class>com.xxx.yyy.listener.AppSessionListener</listener-class>
</listener>