在SSM项目中,处理数据字典问题,在执行监听器的时候加载数据字典,通过@Autowired自动注入Service层,此时出现Service层的空指针异常。
同时我通过debug测试得出,后面面的持久层也是空指针,说明Spring常量池中并没有创建相关的对象。
之后我又在监听器外新建一个类来调用Service层方法,发现这个时候Service层和Dao层都不是空指针,服务可以正常运行,经过我一天的研究,搜索相关知识,找到了问题的解决办法。代码如下
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("处理缓存字典开始");
//获取到上下文对象
ServletContext application = servletContextEvent.getServletContext();
DicService dicService = (DicService) WebApplicationContextUtils.getWebApplicationContext(application).getBean("dicService");
Map<String, List<DicValue>> listMap = dicService.getAll();
//将map解析为上下文中保存的键值对的形式
Set<String> set = listMap.keySet();
for(String key:set) {
application.setAttribute(key, listMap.get(key));
}
System.out.println("处理缓存字典结束");
}
在监听器方法中不需要通过@Autowired来自动注入Service对象,要通过以下代码来获取想要的Service对象:
DicService dicService = (DicService) WebApplicationContextUtils.getWebApplicationContext(application).getBean("dicService");
最后附上全部代码,以便方便观看:
import com.xxxx.ssm.settings.domain.DicValue;
import com.xxxx.ssm.settings.service.DicService;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.List;
import java.util.Map;
import java.util.Set;
//监听哪个域就要实现哪个域的监听器
public class SysInitListener implements ServletContextListener {
/**
* 该方法是用来创建上下文对象的方法,当服务器启动,上下文对象创建
* 对象创建完毕后,马上执行该方法
* @param servletContextEvent 该参数能取得监听的对象,监听的是什么对象,就可以通过该参数取得对象
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("处理缓存字典开始");
ServletContext application = servletContextEvent.getServletContext();
DicService dicService = (DicService) WebApplicationContextUtils.getWebApplicationContext(application).getBean("dicService");
Map<String, List<DicValue>> listMap = dicService.getAll();
//将map解析为上下文中保存的键值对的形式
Set<String> set = listMap.keySet();
for(String key:set) {
application.setAttribute(key, listMap.get(key));
}
System.out.println("处理缓存字典结束");
}
}
最后要强调的是要配置监听器,在web.xml文件中,我们自己写的监听器,一定要配置在spring的监听器后面,代码如下:(通常配置在过滤器后面)
<!--注册spring的监听器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--自己写的监听器-->
<listener>
<listener-class>com.xxxx.ssm.settings.web.listener.SysInitListener</listener-class>
</listener>