SpringBoot拦截器中@Autowired组件报NullPointerException问题
问题原因
空指针的核心原因是你注册拦截器时手动通过new AuthInterceptor()创建了拦截器实例,这个实例不归Spring IoC容器管理,实例内标记@Autowired的JedisConfig属性不会完成依赖注入,运行时jc为null,调用jc.getJedis()自然抛出空指针。
单元测试能正常运行是因为测试上下文里的JedisConfig是Spring直接注入的受管Bean,不存在手动new对象导致依赖不注入的问题。
修复方法
你只需要保证注册到拦截器链的AuthInterceptor实例是Spring容器管理的,就能让@Autowired的依赖正常注入,有两种常用实现方式:
- 方式一:给拦截器加组件注解,注册时直接注入容器管理的拦截器实例
- 给
AuthInterceptor类添加@Component注解,将其声明为Spring受管Bean
@Component public class AuthInterceptor implements HandlerInterceptor { @Autowired private JedisConfig jc; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Jedis jedis = jc.getJedis(); // 业务处理逻辑 return true; } }- 修改拦截器注册配置,注入拦截器Bean后再注册,不要手动new实例
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/user/roleChange"); } } - 给
- 方式二:直接在配置类中通过
@Bean注解声明拦截器Bean,注册时使用该Bean,无需给拦截器类加@Component@Configuration public class WebConfig implements WebMvcConfigurer { @Bean public AuthInterceptor authInterceptor(){ return new AuthInterceptor(); } @Autowired private AuthInterceptor authInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) .addPathPatterns("/user/roleChange"); } }
额外优化建议
你当前JedisConfig中持有的是单例Jedis实例,而Jedis本身是线程不安全的,高并发场景下多线程复用同一个Jedis实例会出现连接错乱、操作异常问题。生产环境建议替换为JedisPool连接池,每次业务操作时从连接池获取一个Jedis实例,使用完成后归还连接,避免长期持有单个Jedis实例。
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

