listener中@Autowired无法注入bean的一种解决方法
背景:使用监听器处理业务,需要使用自己的service方法;
错误:使用@Autowired注入service对象,最终得到的为null;
原因:listener、fitter都不是Spring容器管理的,无法在这些类中直接使用Spring注解的方式来注入我们需要的对象。
解决:写一个bean工厂,从spring的上下文WebApplicationContext 中获取。
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)
@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()+"用户注销!"); }