Springboot在拦截器中无法调用Service层(注入Bean失效)
困扰了一周,一度放弃,只能用的伪造数据,终于找到问题所在!拦截器中注入ServiceBean失效!
报错信息
空指针!无法使用注入的Service,因为根本没用注入进来!!!不光是无法注入,new也不行,哭。
原因
原因: 拦截器加载是在springcontext创建之前完成
解决
自己用工厂或者使用@Bean在拦截器初始化之前让类加载
参考:https://blog.csdn.net/wmh13262227870/article/details/77005920
参考:@Bean方式
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private BbsUserService bbsUserService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(request.getMethod().equals("OPTIONS")){
return true;
}
String token = request.getHeader("token");
if (StrUtil.isBlank(token)) {
throw new CustomException("401", "未获取到token, 请重新登录");
}
String username;
try {
username = JWT.decode(token).getAudience().get(0);
}catch (JWTDecodeException e){
throw new CustomException("401", "权限验证失败, 请重新登录");
}
if(bbsUserService==null){
System.out.println("loginTickerService is null!!!");
BeanFactory factory = WebApplicationContextUtils
.getRequiredWebApplicationContext(request.getServletContext());
bbsUserService = (BbsUserService) factory
.getBean("bbsUserServiceImpl");
}
BbsUser user = bbsUserService.getbyUsername(username);
if(null==user){
throw new CustomException("401", "用户不存在, 请重新登录");
}
//验证jwt
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("liujiaxiang55")).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new CustomException("401", "token不合法, 请重新登录");
}
return true;
}
}
原因详解:拦截器 service执行顺序
SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatc()方法的执行顺序应该是这样的,大致画了个图:其实非常好测试,自己写一个过滤器,一个拦截器,然后在这些方法中都加个断点,一路F8下去就得出了结论。
是因为拦截器加载是在SpringApplicationContext创建之前完成的,所以在拦截器中注入实体CacheService就为null。
参考:Spring Boot 自定义拦截器(HandlerInterceptor)使用@Autowired注入接口为null解决方法
那什么是SpringApplicationContext呢!?
SpringApplicationContext就是Spring上下文!
SpringApplicationContext以后(尽快写一篇博客吧,唉)。