springboot拦截器无法注入redisTemplate的解决方法
在工作中我们经常需要做登录拦截验证或者其他拦截认证功能,基于springboot项目下我们很容易想到结合redis做的分布式拦截,把用户登录或者需要验证的信息放到redis里面。但是在写拦截器的时候发现redisTemplate一直无法注入进来,最后查资料才发现springboot拦截器是在Bean实例化之前执行的,所以Bean实例无法注入。
先看下问题,新建一个拦截器,然后注入redisTemplate
/** * @author: lockie * @Date: 2019/8/13 16:16 * @Description: 接口限流拦截器 */@Componentpublic class AccessLimitIntercept implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(AccessLimitIntercept.class); @Autowiredprivate StringRedisTemplate redisTemplate; /*** 接口调用前检查对方ip是否频繁调用接口* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {try { String test = redisTemplate.opsForValue().get("test"); logger.info(test); } catch (Exception e) {logger.error("API请求限流拦截异常,异常原因:", e); throw new ParameterException(e); }return true; } @Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } private boolean setResponse(Results results, HttpServletResponse response) throws IOException {ServletOutputStream outputStream = null; try {response.setHeader("Content-type", "application/json; charset=utf-8"); outputStream = response.getOutputStream(); outputStream.write(JsonUtil.toJson(results).getBytes("UTF-8")); } catch (Exception e) {logger.error("setResponse方法报错", e); return false; } finally {if (outputStream != null) {outputStream.flush(); outputStream.close(); }}return true; }}
然后配置拦截器,新建一个拦截器config类,我们这里让所有的url都拦截
@Configurationpublic class WebFilterConfig implements WebMvcConfigurer { /*** 多个拦截器组成一个拦截器链* @param registry*/ @Override public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AccessLimitIntercept()).addPathPatterns("/**"); } }
新建一个controller里面增加一个接口,使用postman调用接口
@RestController@RequestMapping("/")public class PingController extends BaseController { @GetMapping(value = "https://www.it610.com/ping") public Results ping() {return succeed("pong", ""); } }
使用postman调用/ping接口,发现返回系统错误
文章图片
控制台发现是空指针的错误,定位错误发现当我们想获取redis里面key是test的值时,发现redisTemplate没有是空的没有注入进来
文章图片
解决问题:
知道拦截器执行在bean实例化前执行的,那么我们就让拦截器执行的时候实例化拦截器Bean,在拦截器配置类里面先实例化拦截器,然后再获取
文章图片
@Configurationpublic class WebFilterConfig implements WebMvcConfigurer { /*** 这里需要先将限流拦截器入住,不然无法获取到拦截器中的redistemplate* @return*/ @Bean public AccessLimitIntercept getAccessLimitIntercept() {return new AccessLimitIntercept(); } /*** 多个拦截器组成一个拦截器链* @param registry*/ @Override public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(getAccessLimitIntercept()).addPathPatterns("/**"); } }
使用postman再次请求就可以访问到
文章图片
【springboot拦截器无法注入redisTemplate的解决方法】到此这篇关于springboot拦截器无法注入redisTemplate的解决方法的文章就介绍到这了,更多相关springboot拦截器无法注入redisTemplate内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- Activiti(一)SpringBoot2集成Activiti6
- 人生感悟记#环境仪器宋庆国成长记#072
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 视频转换器哪种好用()
- NeuVector 会是下一个爆款云原生安全神器吗()
- 操作系统|[译]从内部了解现代浏览器(1)
- 探索免费开源服务器tomcat的魅力