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         }}
原文地址:https://www.cnblogs.com/daixianjun/p/filter-aotowired.html