今天在过滤器(@Component注解将过滤器放入spring容器中)中通过@Autowired注入RedisTemplate redisTemplate;时,发现redisTemplate一直为空。
先说解决方式:
在过滤器的init()方法中获取servletContext,再从servletContext中获取ApplicationContext,再从ApplicationContext获取bean注入
@Override
public void init(FilterConfig config) throws ServletException {
ServletContext sc = config.getServletContext();
XmlWebApplicationContext cxt = (XmlWebApplicationContext) WebApplicationContextUtils.getWebApplicationContext(sc);
//或者ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
if(cxt != null && cxt.getBean("tbUserLoginService") != null && tbUserLoginService == null){
tbUserLoginService = (TbUserLoginService) cxt.getBean("tbUserLoginService");
redisTemplate = (RedisTemplate) cxt.getBean("redisTemplate");
LOGGER.info("tbUserLoginService 注入");
}
}
出现问题的原因:
猜测是因为过滤器是属于tomcat的,在filter上加spring的注解是无用的,因为会生成两个该filter的实例A和B(A:tomcat的容器管理,B为spring容器管理)。
A可以读取web.xml中的配置信息,A是没有办法autowired的;B则可以用@autowired注入。但是我们的请求最终进入的是A,所以A中的注入的bean无效。