zoukankan      html  css  js  c++  java
  • Filter使用@Autowired注解失败及解决办法

    由一个简单filter的使用引发的“血案”

    前情回顾:项目需要一个filter过滤器来拦截所有请求,过滤器的内容很简单,就是过滤请求url判断用户是否登录。如果用户登录,则更新存在redis里的用户信息过期时间;如果未登录则返回信息给前端,跳转登录。

    1 <filter>
    2    <filter-name>ExtensionFilter</filter-name>
    3    <filter-class>com.extension.filters.ExtensionFilter</filter-class>
    4 </filter>
    5 <filter-mapping>
    6    <filter-name>ExtensionFilter</filter-name>
    7    <url-pattern>/*</url-pattern>
    8 </filter-mapping>
    View Code

    给自己挖的坑:

    首先在这个filter过滤器中,需要从请求头中获取token,根据token从redis中拿到用户信息。此时需要在filter中注入封装好的redis实体bean,我使用@Autowired注解,此时代码编译没有报错,看起来程序没问题。

    接下来就是在坑里转悠直到把坑填上:

    紧接着问题就来了,项目能正常跑起来,但是一请求就报NULLPOINTEREXCEPTION异常,debug调试也找不到原因。折磨了我将近半个小时,终于找到问题。细心阅读并且对Web容器初始化熟悉的朋友应该知道我犯了什么错误了。

    问题:在过滤器中采用@Autowired方式注入

    1 @Autowired
    2 rivate RedisCache redisCache;
    View Code

    然鹅,实际证明注入失败。

    分析原因:Web容器初始化顺序是按照Listener-filter-servlet的顺序进行,因为dispatcherServlet是在filter之后才进行初始化,也就是这个时候我们要自动注入的bean才被初始化。所以此时在filter中自动注入的时候还没有bean,所以会注入失败。

    解决办法:

    1、采用xml配置方式

    • Web.xml这样配置
     1 <filter>
     2    <filter-name>ExtensionFilter</filter-name>
     3    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
     4 <init-param>
     5           <param-name>targetBeanName</param-name>
     6           <param-value>ExtensionFilter</param-value>
     7  </init-param>
     8  <init-param>
     9           <param-name>targetFilterLifecycle</param-name>
    10           <param-value>true</param-value>
    11   </init-param>
    12 </filter>
    13 <filter-mapping>
    14    <filter-name>DelegatingFilterProxy</filter-name>
    15    <url-pattern>/*</url-pattern>
    16 </filter-mapping>
    View Code
    • 在spring配置文件中使用bean标签配置serviceImpl和ExtensionFilter
    1 <bean id="ExtensionFilter" class="com.extension.filters.ExtensionFilter">
    2    <property name="redisCache" ref="redisCache"></property>
    3 </bean>
    4 
    5 <!--要注入的bean-->
    6 
    7 <bean id="redisCache" class="com.htjc.interceptor.redis.RedisCache">   
    8 </bean>
    View Code

    这种方式的重点是在web.xml中用到了DelegatingFilterProxy这个filter代理类。具体用法可以去看看DelegatingFilterProxy源码。

    2、使用ApplicationContext对象获取

    1 //要注入的对象
    2 
    3 private RedisCache redisCache;
    4 
    5 ServletContext context = request.getServletContext();
    6 
    7 ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
    8 redisCache = ctx.getBean(RedisCache.class);
    View Code

    以上内容纯属个人总结,如有问题请在评论区留言!

  • 相关阅读:
    jekins构建自动化项目的步骤
    CRT 和mysql 中文乱码解决方式
    Jenkins的配置(rpm red hat方式)
    MapReduce job.setNumReduceTasks(0)思考
    浏览器angent分析工具
    npm中的 --save-dev
    computed与methods的异同
    JS函数种类详解
    Vue.js和Nodejs的关系
    AJAX复习笔记
  • 原文地址:https://www.cnblogs.com/4king/p/11722235.html
Copyright © 2011-2022 走看看