Springboot在拦截器中无法调用Service层(注入Bean失效)

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下去就得出了结论。

img

参考:过滤器 拦截器 service 执行顺序

是因为拦截器加载是在SpringApplicationContext创建之前完成的,所以在拦截器中注入实体CacheService就为null。

参考:Spring Boot 自定义拦截器(HandlerInterceptor)使用@Autowired注入接口为null解决方法

那什么是SpringApplicationContext呢!?

SpringApplicationContext就是Spring上下文!

SpringApplicationContext以后(尽快写一篇博客吧,唉)。

你可能感兴趣的:(bug解决,spring,过滤器,servlet,java)