Spring的filter中无法@Autowired接口的解决方

2018-11-20  本文已影响4224人  JustBull

作者注:转载请注明出处

1、问题背景:

   最近项目需要,需要在filter中添加拦截用户的角色,判断为一体化角色时,如果用户首次登录,需要强制一体化角色设置支付密码,在代码实现时,filter中无法注入Service中的RoleUtils工具和调用其它系统的接口,获取到注入的参数为null。

2、问题探究:

   在项目启动时,监听器listener最先初始化,然后是过滤器filter,最后是servlet。 Spring监听器在启动时会读取spring配置文件,进行spring容器的初始化。springMVC的dispatcherServlet初始化时会读取springMVC的配置文件,进行springMVC容器的初始化。Spring容器初始化时会实例化各个bean。
过滤器是servlet规范中定义的,并不归spring容器管理,也无法直接注入spring中的bean,所以在filter中无法注入spring的实例。

3、解决办法:

   在Filter的初始化init(FilterConfig filterConfig)方法中,获取Spring的上下文,并获取到bean.
eg:ApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(filterConfig.getServletContext());
RoleUtils bean = context.getBean(RoleUtils.class);
this.roleUtils = bean;
以上即可解决Filter无法注入实例的问题。

以下是代码示例:

public class CheckPasswordFilter   implements Filter {
    public RoleUtils roleUtils;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
        ApplicationContext context = WebApplicationContextUtils
                .getWebApplicationContext(filterConfig.getServletContext());
        RoleUtils bean = context.getBean(RoleUtils.class);
        this.roleUtils = bean;
    }
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
             //在此处即可调用 roleUtils,进行下一步的业务判断
    }
  
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
  
}
  

补充:[spring中WebApplicationContextUtils类说明]

  WebApplicationContextUtils是一个抽象类,其提供了一个很便利的方法来获取spring应用的上下文即WebApplicationContext。
其中的静态方法getWebApplicationContext(ServletContext sc),提供一个ServletContext 类型参数即可。
  其原理十分简单,在spring容器初始化的方法org.springframework.web.context.ContextLoader.initWebApplicationContext(ServletContext)中通过servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);已经将WebApplicationContext的实例放入ServletContext 中了。
  然后在工具类的org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(ServletContext)中就可以通过传入的ServletContext参数获取到WebApplicationContext实例了。

上一篇下一篇

猜你喜欢

热点阅读