美文网首页
Spring的filter中无法@Autowired接口的解决方

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

作者: JustBull | 来源:发表于2018-11-20 17:27 被阅读4224次

    作者注:转载请注明出处

    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实例了。

    相关文章

      网友评论

          本文标题:Spring的filter中无法@Autowired接口的解决方

          本文链接:https://www.haomeiwen.com/subject/qfexqqtx.html