参考: 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 }}