SpringBoot 使用拦截器不能注入Bean问题

原创
2021/05/29 23:53
阅读数 1.6K

在 SpringBoot 的拦截器中使用 @Autowired 注入Bean会报空指针。如下面代码所示:

我们编写了一个请求接口,拦截器针对该请求进行了拦截。

@RestController
@RequiredArgsConstructor
@RequestMapping("/demo")
public class DemoController {

    private final DemoService demoService;

    @GetMapping()
    public String getStr(){
        return "this is a demo";
    }

}
@Component
public class DemoInterceptor implements HandlerInterceptor {

    @Autowired
    private DemoService demoService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        demoService.getStr();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }

}

我们触发拦截器,发现拦截器注入的服务报了空指针。

这是因为SpringBoot 在加载到拦截器的时候,里面 Service 还没有注入到 Bean 容器里面。

 

一、使用 WebApplicationContextUtils

我们通过应用上下文去获取 Bean 容器里的实例。

@Component
public class DemoInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
        DemoService demoService = applicationContext.getBean(DemoService.class);
        demoService.getStr();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }

}

验证结果:

 

二、在WebConfiguration注入拦截器

@Component
public class DemoInterceptor implements HandlerInterceptor {

    @Autowired
    private DemoService demoService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        demoService.getStr();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }

}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private DemoInterceptor demoInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(demoInterceptor).addPathPatterns("/**");
    }

}

验证结果:

 

三、在WebConfiguration将拦截器注成bean

public class DemoInterceptor implements HandlerInterceptor {

    @Autowired
    private DemoService demoService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        demoService.getStr();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }

}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public DemoInterceptor getDemoInterceptor() {
        return new DemoInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getDemoInterceptor()).addPathPatterns("/**");
    }

}

验证结果:

 

四、通过构造方法注入

我们通过 Lombok 的 @RequiredArgsConstructor 注解实现构造注入。

@Component
@RequiredArgsConstructor
public class DemoInterceptor implements HandlerInterceptor {

    private final DemoService demoService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        demoService.getStr();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }

}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private DemoService demoService;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new DemoInterceptor(demoService)).addPathPatterns("/**");
    }

}

验证结果:

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部