一、问题?
这两天遇到SpringBoot拦截器中Bean无法注入问题。下面介绍我的思考过程和解决过程 基于springboot项目下我们很容易想到结合redis做的分布式拦截,把用户登录或者需要验证的信息放到redis里面。 但是在写拦截器的时候发现redisTemplate一直无法注入进来, 最后查资料才发现springboot拦截器是在Bean实例化之前执行的,所以Bean实例无法注入。
二、复原问题代码
先看下问题,新建一个拦截器,然后注入redisTemplate
2.1 先看段代码,能发现有什么问题?
webConfig
@Configuration
public class WebConfig implements WebMvcConfigurer {
@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/**");
}
}
拦截器
@Slf4j
public class TokenValidateInterceptor extends HandlerInterceptorAdapter {
@Resource
private RedisTemplate redisTemplate
;
@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)在这里先感谢大家的到来。 虽然不是太详细,小编已经很努力,给小编来个一键三连(点赞,关注,收藏),小编会越来越努力。。。