为方便有时希望在监听器中使用 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>