版权声明:本文为博主原创文章,未经博主允许不得转载。
今天在项目中遇到了一个问题,在 Filter中注入 Serivce失败,注入的service始终为null。经过一番分析后,问题得到了解决。现在给大家分享一下。以下代码展示区域只展示了部分关键代码。
1、报控制针的代码如下所示:
public class SessionFilter implements Filter{
@Autowired
private SystemService systemService;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
TUser user = this.systemService.findHql("from TUser where userName='admin' ");//此处的 systemService会报空指针异常。
chain.doFilter(request, response);
}
2、解决方案:
2.1、解决方案一如下所示:
public class SessionFilter implements Filter{
@Autowired
private SystemService systemService;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//以下为比较关键的处理区域。
ServletContext sc = request.getSession().getServletContext();//通过HttpServletRequestServletContext
XmlWebApplicationContext cxt =(XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(sc);
if(cxt != null && cxt.getBean("systemService") != null && systemService== null)
systemService= (SystemService ) cxt.getBean("systemService");
TUser user = this.systemService.findHql("from TUser where userName='admin' ");//此时就不会为null了。
chain.doFilter(request, response);
}
2.2、解决方案二如下所示:
public class SessionFilter implements Filter{
private SystemService systemService;
public void init(FilterConfig fConfig) throws ServletException {
ServletContext sc = fConfig.getServletContext();
XmlWebApplicationContext cxt = (XmlWebApplicationContext)WebApplicationContextUtils.getWebApplicationContext(sc);
if(cxt != null && cxt.getBean("systemService") != null && systemService== null)
systemService= (SystemService ) cxt.getBean("systemService");
}
相关原理:
2.2.1如何获取 ServletContext:
1)在javax.servlet.Filter中直接获取
ServletContext context = config.getServletContext();
2)在HttpServlet中直接获取
this.getServletContext()
3)在其他方法中,通过HttpServletRequest获得
request.getSession().getServletContext();
2.2.2 WebApplicationContext 与 ServletContext (转自:http://blessht.iteye.com/blog/2121845):
Spring的 ContextLoaderListener是一个实现了ServletContextListener接口的监听器,在启动项目时会触发contextInitialized方法(该方法主要完成ApplicationContext对象的创建),在关闭项目时会触发contextDestroyed方法(该方法会执行ApplicationContext清理操作)。ConextLoaderListener加载Spring上下文的过程
①启动项目时触发contextInitialized方法,该方法就做一件事:通过父类contextLoader的initWebApplicationContext方法创建Spring上下文对象。
②initWebApplicationContext方法做了三件事:创建 WebApplicationContext;加载对应的Spring文件创建里面的Bean实例;将WebApplicationContext放入 ServletContext(就是Java Web的全局变量)中。
③createWebApplicationContext创建上下文对象,支持用户自定义的上下文对象,但必须继承自ConfigurableWebApplicationContext,而Spring MVC默认使用ConfigurableWebApplicationContext作为ApplicationContext(它仅仅是一个接口)的实 现。
④configureAndRefreshWebApplicationContext方法用 于封装ApplicationContext数据并且初始化所有相关Bean对象。它会从web.xml中读取名为 contextConfigLocation的配置,这就是spring xml数据源设置,然后放到ApplicationContext中,最后调用传说中的refresh方法执行所有Java对象的创建。
⑤完成ApplicationContext创建之后就是将其放入ServletContext中,注意它存储的key值常量。
2.2、解决方案三如下所示:
HandlerInterceptor或者HandlerInterceptorAdapter 来替换Filter。
public class SessionInterceptor implements HandlerInterceptor {
@Autowired
private SystemService systemService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// TODO Auto-generated method stub
}
}