zoukankan      html  css  js  c++  java
  • Filter 中注入失败问题

    参考: https://www.cnblogs.com/digdeep/p/4770004.html?tvd

    https://www.cnblogs.com/EasonJim/p/7666009.html

    Spring的自动注入中普通的POJO类都可以使用@Autowired进行自动注入,但是除了两类:Filter和Servlet无法使用自动注入属性。(因为这两个归Web容器管理== tomcat 容器)。

    我建立一个全局拦截器,当然,我把它命名为LoginFilter,它继承了Filter,web应用启动的顺序是:listener->filter->servlet,而因为项目应用了spring mvc,所以我们会有一个配置文件(applixationContext.xml),我们在配置spring时会用到spring的listener,它会读取application.xml里的配置对spring context进行初始化;项目启动时,先初始化listener,因此配置在applicationContext.xml里的bean会被初始化和注入;然后再来就filter的初始化,再接着才到我们的dispathServlet的初始化,因此,当我们需要在filter里注入一个注解的bean时,就会注入失败,因为filter初始化时,注解的bean还没初始化,没法注入。

    1、在我们的LoginFilter中加入需要注入的属性
    /**
    * userService属性
    */
    private UserService userService;
    2、在LoginFilter的init()方法中获取 ServletContext
    ①这里有三种方式获取ServletContext

    1)在javax.servlet.Filter中直接获取 

    ServletContext context = config.getServletContext(); 

    2)在HttpServlet中直接获取 

    this.getServletContext() 

    3)在其他方法中,通过HttpServletRequest获得 

    request.getSession().getServletContext();

    3、然后在LoginFilter中获取我们的WebApplicationContext上下文
    WebApplicationContext cxt =WebApplicationContextUtils.getWebApplicationContext(sc);
    从下面spring源码的可以看到WebApplicationContextUtils.getWebApplicationContext(sc)需要传入一个ServletContext对象(就是我们上面获取的)我们把sc放进去

    public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
    return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }
    4、从WebApplicationContext上下文中获取bean,赋值给我们的userService
    userService = (UserService) cxt.getBean(UserService.class);

    示例代码

     1 @Autowired
     2     private RedisClient redisClient;
     3     @Autowired
     4     McMerchantDao mcMerchantDao;
     5 
     6     /**
     7      * 具体验签方法
     8      * 1. 从数据库中取 apiKey(可以利用缓存)
     9      * 2. 比较参数验签是否合法
    10      *
    11      * @param request
    12      * @param requestWrapper
    13      */
    14     @Override
    15     public void sign(HttpServletRequest request, ServletRequest requestWrapper) {
    16         ServletContext sc = request.getSession().getServletContext();
    17         WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(sc);
    18 
    19         if (Objects.nonNull(cxt)) {
    20             if (Objects.isNull(redisClient)) {
    21                 redisClient = (RedisClient) cxt.getBean("redisClient");
    22             }
    23             if (Objects.isNull(mcMerchantDao)) {
    24                 mcMerchantDao = (McMerchantDao) cxt.getBean(McMerchantDao.class);
    25             }
    26         }}
  • 相关阅读:
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    VS2012/2013/2015/Visual Studio 2017 关闭单击文件进行预览的功能
    解决 IIS 反向代理ARR URLREWRITE 设置后,不能跨域跳转 return Redirect 问题
    Spring Data JPA one to one 共享主键关联
    JHipster 问题集中
    Spring Data JPA 定义超类
    Spring Data JPA查询关联数据
    maven命名
    maven仓库
    Jackson读取列表
  • 原文地址:https://www.cnblogs.com/daixianjun/p/filter-aotowired.html
Copyright © 2011-2022 走看看