1. 问题描述 在学习Redis实战课程过程中,需要用拦截器实现登录验证功能,其需要从Redis中获取用户信息,大致功能逻辑如图
这里一个问题,拦截器里使用Redis时,自然需要使用 StringRedisTemplate ,然而发现不能在拦截器类 LoginInterceptor 注入 StringRedisTemplate,因为拦截器执行在bean实例化前执行的,拦截器会先加载,所以 StringRedisTemplate 还没有被实例化
1 2 3 4 5 6 7 8 @Component public class LoginInterceptor implements HandlerInterceptor { @Resource private StringRedisTemplate stringRedisTemplate; ... }
报错信息:
1 2 java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis .core.StringRedisTemplate.opsForHash()" because "this.stringRedisTemplate" is null at com.hmdp.utils.LoginInterceptor.preHandle(LoginInterceptor.java:50) ~[classes/:na]
2. 解决方法 2.1 方法一 在 WebMvcConfigurer 里注入 StringRedisTemplate,并把 StringRedisTemplate 作为 LoginInterceptor 的一个属性,然后用有参构造函数传递到 LoginInterceptor 里去,也是黑马视频教程的用法
拦截器配置类:MvcConfig.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public class MvcConfig implements WebMvcConfigurer { @Resource private StringRedisTemplate stringRedisTemplate; @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor (stringRedisTemplate)) .excludePathPatterns( ... ); } }
拦截器类:LoginInterceptor.class
1 2 3 4 5 6 7 8 9 10 11 @Component public class LoginInterceptor implements HandlerInterceptor { private StringRedisTemplate stringRedisTemplate; public LoginInterceptor (StringRedisTemplate stringRedisTemplate) { this .stringRedisTemplate = stringRedisTemplate; } ... }
2.2 方法二 还是在拦截器类 LoginInterceptor 注入 StringRedisTemplate,现在知道拦截器执行是在bean实例化前执行的,那么我们就让拦截器执行的时候实例化拦截器Bean,在拦截器配置类里面先实例化拦截器,然后再获取 。我也实验了代码,确实可行
LoginInterceptor.class
1 2 3 4 5 6 7 8 @Component public class LoginInterceptor implements HandlerInterceptor { @Resource private StringRedisTemplate stringRedisTemplate; ... }
MvcConfig.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Configuration public class MvcConfig implements WebMvcConfigurer { @Bean public LoginInterceptor getLoginInterceptor () { return new LoginInterceptor (); } @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(getLoginInterceptor()) .excludePathPatterns( ... ); } }
参考资料:springboot拦截器无法注入redisTemplate的解决方法