背景:使用監聽器處理業務,須要使用本身的service方法;spring
錯誤:使用@Autowired注入service對象,最終獲得的爲null;session
緣由:listener、fitter都不是Spring容器管理的,沒法在這些類中直接使用Spring註解的方式來注入咱們須要的對象。app
解決:寫一個bean工廠,從spring的上下文WebApplicationContext 中獲取。ide
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * @ClassName: SpringJobBeanFactory*/ @Component public class SpringJobBeanFactory implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringJobBeanFactory.applicationContext=applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { if (applicationContext == null){ return null; } return (T)applicationContext.getBean(name); } public static <T> T getBean(Class<T> name) throws BeansException { if (applicationContext == null){ return null; } return applicationContext.getBean(name); } }
監聽器裏獲取service,使用getBean(XXX.class)spa
@Override public void sessionDestroyed(HttpSessionEvent event) { logger.debug("session銷燬了"); UserCountUtils.subtract();//在線人數-1 HttpSession session = event.getSession();// 得到Session對象 ServletContext servletContext = session.getServletContext(); Account acc = (Account) session.getAttribute("user"); if(acc!=null){ @SuppressWarnings("unchecked") Map<String, String> loginMap = (Map<String, String>) servletContext.getAttribute("loginMap"); loginMap.remove(acc.getUserName()); servletContext.setAttribute("loginMap", loginMap); session.removeAttribute("user"); acc.setOnlineState(false); //註銷成功修改用戶在線狀態爲 離線 //WebApplicationContext appctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); //AccountService accountService = appctx.getBean(AccountService.class); AccountService accountService = SpringJobBeanFactory.getBean(AccountService.class); accountService.updateAccount(acc); logger.debug(acc.getUserName()+"用戶註銷!"); }