一、问题?
这两天遇到SpringBoot拦截器中Bean无法注入问题。下面介绍我的思考过程和解决过程
基于springboot项目下我们很容易想到结合redis做的分布式拦截,把用户登录或者需要验证的信息放到redis里面。
但是在写拦截器的时候发现redisTemplate一直无法注入进来,
最后查资料才发现springboot拦截器是在Bean实例化之前执行的,所以Bean实例无法注入。
二、复原问题代码
先看下问题,新建一个拦截器,然后注入redisTemplate
2.1 先看段代码,能发现有什么问题?
- webConfig
/**
* @program: onion
* @description: webConfig
* @author: Mr.Teddy
* @create: 2020-09-04 09:33
**/
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 这里需要先将限流拦截器入住,不然无法获取到拦截器中的redistemplate
* @return
*/
@Bean
public TokenValidateInterceptor getAccessLimitIntercept() {
return new TokenValidateInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(getAccessLimitIntercept()) //添加拦截器
.addPathPatterns("/**") //拦截所有请求
.excludePathPatterns("/swagger-ui.html") //接口文档
.excludePathPatterns("/swagger-ui.html/**")
.excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/webjars/**");
}
}
- 拦截器
/**
* @program: teddy_manage
* @description: 拦截器
* @author: Mr.Teddy
* @create: 2020-10-19 14:40
**/
@Slf4j
public class TokenValidateInterceptor extends HandlerInterceptorAdapter {
@Resource
private RedisTemplate redisTemplate; // 注入redis
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
...
log.info("--------------处理请求前---------------");
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) {
log.info("--------------处理请求完成后视图渲染之前的处理操作---------------");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
log.info("---------------视图渲染之后的操作-------------------------0");
}
2.2 哈哈哈,看不出来什么毛病吧? 来看代码结果
原因是由于拦截器加载的时间点在springcontext之前,所以在拦截器中注入为null。
三、解决办法
知道拦截器执行在bean实例化前执行的,那么我们就让拦截器执行的时候实例化拦截器Bean,在拦截器配置类里面先实例化拦截器,然后再获取
- 在WebMvcConfigurer的实现类中给容器实例化拦截器就解决啦。
😁 作者:Teddy (公众号:鸡仓故事汇)
ok!到这里就大功告成,小编(Teddy)在这里先感谢大家的到来。
虽然不是太详细,小编已经很努力,给小编来个一键三连(点赞,关注,收藏),小编会越来越努力。。。